C++ std::variant - 类型特征以验证包含的变体类型是否满足某些假设
C++ std::variant - Type traits to verify that the contained variant types meet some assumptions
假设我有一些类型都有一个共同的父类:
struct some_tag;
struct A : some_tag;
struct B : some_tag;
struct C : some_tag;
struct D : some_tag;
单独地,可以使用以下方法测试一种类型是否是 some_tag
的子类型:
template <typename T>
using has_some_tag = std::is_base_of<some_tag, T>;
但是,假设我有一些变体可以接受任何数字和这些类型的任何组合,例如:
using variant_1 = std::variant<A,B,C>;
using variant_2 = std::variant<B,C>;
using variant_3 = std::variant<D,A>;
...
然后,假设我使用这些变体类型作为模板参数传递给某些 class,这些 class 具有处理每种类型的访问逻辑。
template <typename V>
struct some_other_type;
对于类型 V
,我希望 static_assertions 符合以下条件:
V
是变体
V
是一个变体,它只接受从 some_tag
. 继承的类型
我想我把所有的小部分都放在一起了,但我想不出检查变体类型的最佳方法。
我认为我需要的是一种特征,它可以有效地断言特定特征适用于每种基础类型。我应该指出,这里可以做的唯一假设是 V
应该只包含从 some_tag
继承的东西,但我们不能假设这需要的东西的顺序或数量。
有什么指点吗?
您可以使用偏特化:
template<class>
struct checker : std::false_type {};
template<class... Ts>
struct checker<std::variant<Ts...>> :
std::bool_constant<(has_some_tag<Ts>::value && ...)> {};
然后写:
template<typename V>
struct some_other_type {
static_assert(checker<V>::value);
};
或者,您可以使用 std::conjunction
而不是 &&
折叠:
template<class... Ts>
struct checker<std::variant<Ts...>> : std::conjunction<has_some_tag<Ts>...> {};
编辑。 std::integral_constant<bool>
已替换为 std::bool_constant
。谢谢,max66.
假设我有一些类型都有一个共同的父类:
struct some_tag;
struct A : some_tag;
struct B : some_tag;
struct C : some_tag;
struct D : some_tag;
单独地,可以使用以下方法测试一种类型是否是 some_tag
的子类型:
template <typename T>
using has_some_tag = std::is_base_of<some_tag, T>;
但是,假设我有一些变体可以接受任何数字和这些类型的任何组合,例如:
using variant_1 = std::variant<A,B,C>;
using variant_2 = std::variant<B,C>;
using variant_3 = std::variant<D,A>;
...
然后,假设我使用这些变体类型作为模板参数传递给某些 class,这些 class 具有处理每种类型的访问逻辑。
template <typename V>
struct some_other_type;
对于类型 V
,我希望 static_assertions 符合以下条件:
V
是变体V
是一个变体,它只接受从some_tag
. 继承的类型
我想我把所有的小部分都放在一起了,但我想不出检查变体类型的最佳方法。
我认为我需要的是一种特征,它可以有效地断言特定特征适用于每种基础类型。我应该指出,这里可以做的唯一假设是 V
应该只包含从 some_tag
继承的东西,但我们不能假设这需要的东西的顺序或数量。
有什么指点吗?
您可以使用偏特化:
template<class>
struct checker : std::false_type {};
template<class... Ts>
struct checker<std::variant<Ts...>> :
std::bool_constant<(has_some_tag<Ts>::value && ...)> {};
然后写:
template<typename V>
struct some_other_type {
static_assert(checker<V>::value);
};
或者,您可以使用 std::conjunction
而不是 &&
折叠:
template<class... Ts>
struct checker<std::variant<Ts...>> : std::conjunction<has_some_tag<Ts>...> {};
编辑。 std::integral_constant<bool>
已替换为 std::bool_constant
。谢谢,max66.