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

可变模板数据结构

龚迪
2023-03-14

可变参数模板是接收不同数量参数的模板,可用于可与泛型类型一起运行的模型

法典:

    #include <iostream>
    
    template <class ...Rest>
    struct Test {};
    
    template <class T, class ...Rest>
    struct Test <T, Rest...> {
        Test(T first, Rest... rest)
          : first(first)
         {}
    
        T first;
    };
    
    template <class T>
    void Print1(T &data)
    {
        std::cout << data.first << std::endl;
    }
    
    template <class T, class ...Rest>
    void Print2(Test<T, Rest...> &data)
    {
        std::cout << data.first << std::endl;
    }
    
    template <class T>
    struct Helper;
    
    template <class T, class ...Rest>
    struct Helper<Test<T, Rest...>> {
       static void Print(Test<T, Rest...> &data){
           std::cout << data.first << std::endl;
       }
    };
    
    int main() {
        Test<int, float, bool> ex(15, 41.59, true);
    
        using type = decltype(ex); //Test<int, float, bool>
      
        Print1(ex);
    
        Print2(ex);
    
        Helper<type>::Print(ex);
      
        std::cout << "END!" << std::endl;
        return 0;
    }

观察:问这个问题的原因是为了理解varidiac模板操作,因此我不关心程序的使用,在上面的示例中:测试类正在失去对生成的子类的访问权(rest…)

问题是:

  1. 第一个值得怀疑的话题是:我知道函数和类可以有模板,但模板有什么用呢
template <class T, class ...Rest>
void Func(T first, Rest ...rest){
    std::cout << first << std::endl;

    Func(rest...); //1 call is [T=float,Rest=<bool>], and 2 call is [T=bool] (Futures calls)
}
//Call: Func (1, 1.55, true), [T equals "int", Rest equals <float, bool>]

疑问的第二个主题:在函数“Print2”中,为什么为Print2调用推导的模板是

怀疑的第三个主题:这个主题提到了第一个主题(其中

第四个疑问话题:这个话题提到了第二个话题(Print2的模板推导出来)为什么只需要通过测试

第 4 个主题的补充:帮助::P rint(ex),“类型”相当于 Test

提前感谢。

共有1个答案

淳于鹏
2023-03-14

我把这个答案献给@super,它提供了研究的链接和技术名称。谢谢!

1和3.假设模板主要是:

template <size_t ...Rest>
struct Test {
   int value = 1;
};

这意味着其他方法(部分专门化)可以被扣除,通过这种方法可以定义结构/类中的不同方法和值,例如:

template <size_t A>
struct Test <A, A*2> {
  int value = 2;
}

任何使用 2 个参数初始化的“Test”结构,第二个是第一个 (A*2) 的双精度,其值 = 2。例:

Test<5, 10> -> value = 2
Test <3, 6> -> value = 2;

Anything other than: "<A, A * 2>" will be assigned to the primary template

Test <1, 2, 3, 4> -> value = 1;
Test <4, 5> -> value = 1;
Test <3, 6, 8> -> value = 1;

也就是说,回答第一个主题:

template <class ...Rest>
struct Test {
  int value = 1;
};

template <class T, ...Rest>
struct Test <T, Rest...> {
  int value = 2;
};

辅助模板的条件必须满足主模板,在本例中为:“模板

以下示例:

Test<int, bool> -> value = 2
Test <bool, float> -> value = 2
Test <bool> -> value = 2
Test <std::string> -> value = 2

但您也可以创建其他辅助模板:

template <class ...Rest>
struct Test {
  int value = 1;
};

template <>
struct Test <int, float> {
  int value = 2;
};

template <class ...Rest>
struct Test <int, float, bool, Rest...> {
  int value = 3;
};

在上面的这个例子中,您是说:

如果类型为”

如果类型为

示例:

Test <int, float> -> value = 2

Test <int, float, bool> -> value = 3
Test <int, float, bool, std::string> -> value = 3
Test <int, floot, bool, std::string, char> -> value = 3

Any other that does not satisfy any of the secondary templates will be assigned to the primary

Test <bool, float> -> value = 1
Test <int> -> value = 1
Test <int, float, char> -> value = 1

2.让我们假设下面的代码

...
template <class T, class ...Rest>
void Print(T data, Rest ...others){
   std::cout << data.first << std::endl;
}

int main(){
  Test<int, float, bool> ex(15, 41.59, true);

  Print(ex);
  return 0;
}

print等待作为参数(T数据,Rest...其他),即:“data”是T类型的。然后T数据将是“ex”

如果我们将打印功能更改为“打印”(测试

"

请参阅下面的示例:

...
template <class A, class B, class C>
void Print(Test<A, B, C> &data, A za, B zq){
    std::cout << data.first << std::endl;
    std::cout << za << std::endl; //float
    std::cout << zq << std::endl; //bool
}

int main(){
  Test<int, float, bool> ex(15, 41.59, true);

  Print(ex, 50);
  return 0;
}

再一次"

a是“int”

B是“浮动”

c是“布尔”

函数“Print”的第二个参数(A za)必须与被“A”(int)扣除的参数的类型(int)相同,与第三个参数(B zq)相同

3.让我们假设下面的代码:

template <class T>
struct Helper {
  int value = 1;
};

template <>
struct Helper <int> {
  int value = 2;
};

template <class A, class B, class C>
struct Helper<Test<A, B, C>> {
   int value = 3;

   void PrintA(A value){}

   void PrintB(B value){}

   void PrintAll(A aval, B bval, C cval){}
};

任何用单个

用不同于的单个参数初始化的任何“Helper”结构

示例:

Helper<int> -> value = 2

Helper<Test<int,bool,float>> -> value = 3
Helper<Test<int,float,char>> -> value = 3
Helper<Test<char,std::string,double>> -> value = 3

Anything other than: "<int>" and "<Test<A,B,C>>" will be assigned to the primary template

Helper <bool> -> value = 1
Helper <float> -> value = 1
Helper <char> -> value = 1

请注意,辅助模板必须满足主要模板,即:模板

因此,定义“助手”之后的辅助模板必须只包含一个“T”,示例

样板

这意味着:要传递给Helper的模板必须是满足表达式的struct / class类型,因此:

助手

助手

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

  • 模板变量数据源 text 类型的变量是可以添加数据源属性的,添加数据源属性后,这个 text变量在后台设置时就可以让用户选择这个变量的值,如果用户选择文章分类,选择页面,选择导航. 配置格式: "vars": { "varName1": { "title": "测试 text", /*后台设置时 input 的 label*/ "value": "1", /

  • 模板变量数据源 模板变量数据源,简称模板数据源;text 类型的变量是可以添加数据源属性的,添加数据源属性后,这个 text变量在后台设置时就可以让用户选择这个变量的值,如果用户选择文章分类,选择页面,选择导航. 配置格式: "vars": { "varName1": { "title": "测试 text", /*后台设置时 input 的 label*/

  • 要解决的问题: 怎么创建一个拥有1个、2个或者更多的初始化器的类? 怎么避免创建一个实例而只拷贝部分的结果? 怎么创建一个元组? 最后的问题是关键所在:考虑一下元组!如果你能创建并且访问一般的元组,那么剩下的问题也将迎刃而解。 这里有一个例子(摘自“可变参数模板简述(A brief introduction to Variadic templates)”(参见参考)),要构建一个广义的、类型安全的

  • 我希望打印函数根据“值”的类型来做不同的事情。

  • 当我编译时,我得到了这些错误: