给定类型 T 和某些类型的 std::variant,如何回答问题:T 是该变体的成员类型吗?
使用类型特征样式:
// Define a general type trait
template<typename T, typename VAR>
struct is_member_of_variant : std::false_type {};
template<typename T, typename VAR>
constexpr static bool is_member_of_variant_v = is_member_of_variant<T, VAR>::value;
// Answer the intermediate question: Is T a member of a list of types? (In the generic case, the answer is no)
template<typename T, typename... TYPES>
struct is_member_of_typelist : std::false_type {};
// The answer is yes, if T is the same as the first member of the type list
// or if it is yes for the remaining tail of the type list (this enters recursion)
template<typename T, typename U, typename... TYPES>
struct is_member_of_typelist<T, U, TYPES...> : std::disjunction<std::is_same<T, U>, is_member_of_typelist<T, TYPES...>> {};
// Now define the type trait specialization for variants
template<typename T, typename... TYPES>
struct is_member_of_variant<T, std::variant<TYPES...>> : is_member_of_typelist<T, TYPES...> {};
// and some test code
using MyVar = std::variant<std::monostate, int, double, int>;
int main()
{
static_assert(!is_member_of_typelist<int, char, float>::value);
static_assert( is_member_of_typelist<int, int, float>::value);
static_assert( is_member_of_typelist<float, int, float>::value);
static_assert(!is_member_of_typelist<float, int, double>::value);
static_assert(!is_member_of_variant_v<int, double>); // 'double' is not a variant
static_assert(!is_member_of_variant_v<float, MyVar>); // 'float' is no member of 'MyVar'
static_assert(!is_member_of_variant_v<char, MyVar>); // 'char' is no member of 'MyVar'
static_assert( is_member_of_variant_v<double, MyVar>); // 'double' is a member of 'MyVar'
static_assert( is_member_of_variant_v<int, MyVar>); // 'int' is a member of 'MyVar' (even two times!)
static_assert(!is_member_of_variant_v<void, MyVar>); // 'void' is no member of 'MyVar' (void cannot be a member of any variant)
static_assert( is_member_of_variant_v<std::monostate, MyVar>); // 'monostate' is a member of 'MyVar'
return 0;
}