C++ std::variant - 类型特征以验证所包含的变体类型是否满足某些假设

标签 c++ templates c++17 variadic-templates typetraits

假设我有一些类型,它们都有一个共同的父级:

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>;
...

然后,假设我使用这些变体类型作为模板参数传递给某个类,该类具有处理每种类型的访问逻辑。

template <typename V>
struct some_other_type;

对于类型 V,我希望使用 static_assertions 来满足以下条件:

  1. V 是一个变体
  2. 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 。谢谢,ma​​x66

关于C++ std::variant - 类型特征以验证所包含的变体类型是否满足某些假设,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58683438/

相关文章:

c++ - 当返回类型是 vector 容器时,是否有在 c++ 中返回 Null 的解决方法?

c++ - 返回常量对象并将其分配给非常量对象

c++ - 将 constexpr const char* 传递给模板函数?

c++ - 一个函数的类模板特化

c++ - 在 C++17 中使用 noexcept 的 std::function

c++ - 什么是 & -> double& 的变量

c++ - 错误 : identificator not defined in c++

c++ - 通过 typedef 显式模板实例化

c++ - 这个 "size of array"模板函数是如何工作的?

c++ - std::make_index_sequence 和 std::index_sequence 的细节