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

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

比方说,我有一些类型的集合都有共同的父代:

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的事物,但我们不能对此所包含的事物的顺序或数量做出假设。

任何指针?

c++ templates c++17 typetraits
1个回答
1
投票

您可以使用部分专业化:

template<class>
struct checker : std::false_type {};

template<class... Ts> 
struct checker<std::variant<Ts...>> : 
    std::integral_constant<bool, (has_some_tag<Ts>::value && ...)> {};

然后写:

template<typename V>
struct some_other_type {
    static_assert(checker<V>::value);
};
© www.soinside.com 2019 - 2024. All rights reserved.