微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

如何将类型与数字关联

如何解决如何将类型与数字关联

我希望能够为特定类型列表的每种类型生成一个数字。

即对于以下 2 个类型列表(其中 Group 的工作方式类似于 std::variant):

class myclass;

using GroupA = Group<int,double,myclass>;

static_assert( GroupA::type_number<int> == 0 );
static_assert( GroupA::type_number<double> == 1 );
static_assert( GroupA::type_number<myclass> == 2 );


using GroupB = Group<double,myclass>;  // different group => different numbering

static_assert( GroupB::type_number<double> == 0 );
static_assert( GroupB::type_number<myclass> == 1 );

我尝试通过 Types 进行递归,但我无法在每个 type 上得到一个模板参数

template < typename ... Types> 
struct Group
{
    
    template < typename T > 
    constexpr static int type_number = 0;
    
    template < typename T,typename ... Types >
    constexpr static int type_number = type_number<Types...> + 1;

};

我正在模仿 any/variant 并且我希望能够对它们的向量进行排序。

解决方法

大致如下:

template <typename T,typename Head,typename ... Tail>
constexpr int TypeNumber(int start) {
  if constexpr (std::is_same_v<T,Head>) {
    return start;
  } else {
    return TypeNumber<T,Tail...>(start + 1);
  }
}

template < typename ... Types> 
struct Group
{
    template < typename T > 
    constexpr static int type_number = TypeNumber<T,Types...>(0);
};

Demo

,

递归方式使代码编译时间更长。 诀窍是从一开始就使用配对,

然后,您可以使用重载按索引或按类型“选择”Text(双标会导致模棱两可的调用)。

Pair

Demo

template <typename T,std::size_t I> struct Pair { // possibly data,as `T data;` for tuple }; template <typename T,std::size_t I> constexpr std::integral_constant<std::size_t,I> type_number(Pair<T,I>) { return {}; } template <typename Seq,typename ... Ts> struct GroupImpl; template <std::size_t ... Is,typename ... Ts> struct GroupImpl<std::index_sequence<Is...>,Ts...> : Pair<Ts,Is>... { template <typename T> constexpr static auto type_number() { return decltype(::type_number<T>(GroupImpl{})){}; } }; template <typename ... Ts> using Group = GroupImpl<std::make_index_sequence<sizeof...(Ts)>,Ts...>; 不是 C++11,但可以在 C++11 中实现 (在实例化数量上是线性的甚至是对数的)(在 C++14 中,在 std 中,编译器甚至可能使用内在的来只有一个实例化 :-) )

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。