当前位置: 首页 > 知识库问答 >
问题:

如何从可变模板类包中的每个类型恢复非typename模板参数?

咸琪
2023-03-14

我试图从一组可变的模板类(其中每个类都有一个非类型参数)中恢复非typename模板参数,以便在另一种类型中将它们用作整数序列。

下面的代码显示了我所拥有的。整数序列/成员序列是从元组中抄袭出来的。

template<std::size_t... Integers>
struct size_t_sequence {
    using type = size_t_sequence<Integers...>;
};

template <std::size_t, typename>
struct push_size_t_sequence;

template <std::size_t I, std::size_t... Integers>
struct push_size_t_sequence<I, size_t_sequence<Integers...>>
    : size_t_sequence<I, Integers...> {};

template <std::size_t N, std::size_t Head, std::size_t... Tail>
struct make_size_t_sequence
    : push_size_t_sequence<Head, typename make_size_t_sequence<N - 1, Tail...>::type>::type {};

template<std::size_t I, std::size_t... OneLeft>
struct make_size_t_sequence <2, I, OneLeft...> :
    push_size_t_sequence<I, size_t_sequence<OneLeft...>>::type {};



template<typename... Members>
struct member_sequence {
    using type = member_sequence<Members...>;
};
template <typename, typename>
struct push_member_sequence;

template <typename M, typename... Members>
struct push_member_sequence<M, member_sequence<Members...>>
    : member_sequence<M, Members...> {};

template <std::size_t N, typename Head, typename... Tail>
struct make_member_sequence
    : push_member_sequence<Head, typename make_member_sequence<N - 1, Tail...>::type>::type {};

template<typename M, typename... OneLeft>
struct make_member_sequence <2, M, OneLeft...> :
    push_member_sequence<M, member_sequence<OneLeft...>>::type {};


template<typename>
struct unpack_sequence_impl;

template<template<std::size_t> class... T, std::size_t... DimensionSizes>
struct unpack_sequence_impl<member_sequence<T<DimensionSizes>...>> {
    using member_types = member_sequence<T<DimensionSizes>...>;
    using size_types = size_t_sequence<DimensionSizes...>;
};

template<typename... Members>
struct unpack_sequence : 
    unpack_sequence_impl<make_member_sequence<sizeof...(Members), Members...>> {
    using base_t = unpack_sequence_impl<make_member_sequence<sizeof...(Members), Members...>>;
    using member_types = typename base_t::member_types;
    using size_types = typename base_t::size_types;
};


template<std::size_t N>
class example {
    int s = N;
};

int main()
{
    auto mem_sequence = make_member_sequence<3, example<3>, example<2>, example<1>>::type();
    auto integer_sequence = make_size_t_sequence<3, 3,2,1>::type();
    auto un_mem_sequence = unpack_sequence<example<3>, example<2>, example<1>>::member_types();
    auto un_size_sequence = unpack_sequence<example<3>, example<2>, example<1>>::size_types();
}

mem_sequenceinteger_sequence的类型是member_sequence

我怎样才能做到这一点?

谢谢你的帮助!

提姆

编辑:

为了澄清,我试图完成的是从一个模板类恢复模板参数,以便在另一个模板类中使用它们。下面是三个模板类:MyObjectMyTupleMyPackMyTupleMyObject对象作为其模板参数。我想恢复MyObject模板参数,用作MyPack对象的模板参数。

template<int N>
MyObject;

template<int... Ns>
MyPack;

template<typename... MyObjects>
MyTuple {};



int main() {
    MyTuple<MyObject<1>,MyObject<2>,MyObject<3>> a;
    MyPack<1,2,3> b;
}

所以我想从MyTuple中的MyObject中提取参数,用于创建MyPack。

编辑2:

第二点澄清:MyTuple不仅仅接受MyObject类型,还接受任何具有一个int模板参数的类型。

template<int N>
MyObject;

template<int N>
MyObject2;

template<int... Ns>
MyPack;

template<typename... MyObjects>
MyTuple {};



int main() {
    MyTuple<MyObject<1>,MyObject<2>,MyObject2<1>,MyObject2<2>> a;
    MyPack<1,2,1,2> b;
}

共有2个答案

那铭
2023-03-14

为了澄清,我试图完成的是从一个模板类恢复模板参数,以便在另一个模板类中使用它们。下面是三个模板类:MyObject、MyTuple和MyPack。MyTuple将MyObject对象作为其模板参数。我想恢复MyObject模板参数,用作MyPack对象的模板参数。

为了好玩,我提出了一个更通用的解决方案,使用双变量模板(模板模板和值模板),不受MyTupleMyObject

template <typename>
struct getMyPack;

template <template <typename...> class C,
          template <int> class ... Cs, int ... Is>
struct getMyPack<C<Cs<Is>...>>
 { using type = MyPack<Is...>; };

下面是一个完整的编译示例

#include <type_traits>

template <int>
struct MyObject1
 { };

template <int>
struct MyObject2
 { };

template <int...>
struct MyPack
 { };

template <typename...>
struct MyTuple
 { };

template <typename>
struct getMyPack;

template <template <typename...> class C,
          template <int> class ... Cs, int ... Is>
struct getMyPack<C<Cs<Is>...>>
 { using type = MyPack<Is...>; };


int main ()
 {
   using T0 = MyTuple<MyObject1<1>, MyObject2<2>, MyObject1<3>>;
   using T1 = MyPack<1, 2, 3>;
   using T2 = typename getMyPack<T0>::type;

   static_assert( std::is_same<T1, T2>::value, "!" );
 }

--编辑--

第二点澄清:MyTuple不仅接受MyObject类型,还接受任何具有int模板参数的类型。

正如我所怀疑的。

我的解决方案未绑定到MyObject,因此应该可以工作。

对前面的示例进行了修改以显示它。

裴姚石
2023-03-14
template <typename>
struct MakeMyPack;

template <int... Ns>
struct MakeMyPack<MyTuple<MyObject<Ns>...>>
{
    using type = MyPack<Ns...>;
};

演示

 类似资料:
  • 假设我有一个模板类 在这个堆栈类中,我调用了一个实用程序类,它也是模板。但是数据类型它的处理是UltityDATA类型。也就是说,如果我们使用以下代码创建类堆栈的对象 在内部,它应该称为UltityMata。我不想向客户透露UltityMyData结构。我已经编写了将MyData转换为UltityMyData的实现。我唯一的要求是在调用库类时如何将数据typename转换为UtilityDATA

  • 在C++11之前,类模板和函数模板只能含有固定数量的模板参数。C++11增强了模板功能,允许模板定义中包含0到任意个模板参数,这就是可变参数模板。可变参数模板的加入使得C++11的功能变得更加强大,而由此也带来了许多神奇的用法。 可变参数模板 可变参数模板和普通模板的语义是一样的,只是写法上稍有区别,声明可变参数模板时需要在typename或class后面带上省略号...: template<ty

  • 我想有一个可变的类模板来生成每种类型的一个方法,例如像下面这样的类模板: 将使方法

  • 我有一个模板类,其中每个模板参数代表内部计算可以处理的一种类型的值。需要模板(而不是函数重载),因为值被作为::any传递,并且它们的类型在运行时之前不清楚。 为了正确地转换为正确的类型,我希望每个变量参数类型都有一个成员列表,类似于这样: 或者,我想将模板参数类型存储在一个列表中,以便对其进行RTTI处理(?)。但如何将它们保存在std::initializer\u列表成员中,我也不清楚。 谢谢

  • 变量通用属性 变量通用属性有title,value,type,tip,rule,message,除了通用属性个别变量还有其它属性,请看每个具体控件; "vars": { "varName1": { "title": "测试 text", /*后台设置时 input 的 label*/ "value": "1", /*变量默认值*/ "type

  • 变量通用属性 变量通用属性有title,value,type,tip,rule,message,除了通用属性个别变量还有其它属性,请看每个具体控件; "vars": { "varName1": { "title": "测试 text", /*后台设置时 input 的 label*/ "value": "1", /*变量默认值*/ "type