此类型是 std::variant 的成员吗?

问题描述 投票:0回答:1

给定类型 T 和某些类型的 std::variant,如何回答问题:T 是该变体的成员类型吗?

c++ metaprogramming type-traits
1个回答
0
投票

使用类型特征样式:

// 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;
}
© www.soinside.com 2019 - 2024. All rights reserved.