当前位置:   article > 正文

C++_可变参数模板_c++可变参数模板

c++可变参数模板

       

目录

1、可变参数模板的用法

2、参数包展开

2.1 递归方式展开

2.2 逗号表达式形式展开 

3、参数包的大小

结语 


前言:

        C++11引入了可变参数模板,他的作用是可以让创建的函数模板或者类模板的模板参数可以接收任意数量参数,在C++11前,只能手写固定数量个模板参数,并且只能接收与之对应数量的参数,有了可变参数模板后,代码就变得更加的灵活了。

1、可变参数模板的用法

        可变参数必须是搭配着模板使用的,具体写法如下:

  1. // Args是一个模板参数包,args是一个函数形参参数包
  2. // 声明一个参数包Args...args,这个参数包中可以接收多个实参。
  3. template <class ...Args>
  4. void ShowList(Args... args)
  5. {}

         可以发现,可变参数模板的写法非常特殊,需要先创建一个模板,并且该模板的参数需要用三个点:’...‘来声明,如上代码,Args就成了一个模板参数包,再用该模板参数去作为args的类型,则args为函数形参参数包,这一类args就可以接收多个实参了(可接收0~n个参数,n>=0)。

2、参数包展开

        虽然args可以接收多个参数,但是无法直接读取这些参数的内容,因此最重要的一步是将args参数包中的内容展开并读取到里面的数据,这也是可变参数模板的一个难点——参数包的展开。

2.1 递归方式展开

        采用类似于递归的方式进行参数包的展开(注意调用参数包的写法),具体代码如下:

  1. #define _CRT_SECURE_NO_WARNINGS 1
  2. #include<iostream>
  3. using namespace std;
  4. template <class T>
  5. void ShowList(const T& t)
  6. {
  7. cout << t << endl;
  8. }
  9. template <class T, class ...Args>
  10. void ShowList(T value, Args... args)//函数重载
  11. {
  12. //展开参数包
  13. cout << value << " ";
  14. ShowList(args...);//当只剩下一个参数时会走第一个ShowList
  15. }
  16. int main()
  17. {
  18. ShowList(1, 'A', string("hello world"));
  19. return 0;
  20. }

         运行结果:

        具体流程如下图所示:

2.2 逗号表达式形式展开 

        除了上述的递归方式,还可以把参数包放到一个数组里, 写法如下:

  1. #define _CRT_SECURE_NO_WARNINGS 1
  2. #include<iostream>
  3. using namespace std;
  4. template <class T>
  5. void PrintArg(T t)
  6. {
  7. cout << t << " ";
  8. }
  9. template <class ...Args>
  10. void ShowList(Args... args)
  11. {
  12. int arr[] = { (PrintArg(args), 0)... };//特殊的写法
  13. cout << endl;
  14. }
  15. int main()
  16. {
  17. ShowList(1, 'A', "hello world");
  18. return 0;
  19. }

        运行结果:

        具体过程:{(printarg(args), 0)...}将会展开成((printarg(arg1),0), (printarg(arg2),0), (printarg(arg3),0), etc... ),因为是逗号表达式,所以先执行逗号前面的内容,即(printarg(args),因此会先去调用函数printarg,也就是说在构造arr数组的过程就将参数包展开了,并且该数组arr的全部元素都是0(因为逗号表达式的结果取最后一个),该数组的大小是参数包的大小,并且参数包中有多少个参数就有多少个元素0,数组的最终结果应该是:arr[sizeof...(args)] = {0,0,0..}。

3、参数包的大小

         参数包的大小即该参数包里总共有多少个参数,与参数的类型无关,只与个数有关,示例代码如下:

  1. #define _CRT_SECURE_NO_WARNINGS 1
  2. #include<iostream>
  3. using namespace std;
  4. template<class ...Args>
  5. void func(Args... args)
  6. {
  7. cout << __FUNCTION__ << ":" << sizeof...(args) << endl;//注意求参数包的写法
  8. }
  9. int main()
  10. {
  11. func();//一个参数没有则参数包为0
  12. func('A', "hello world");//两个参数,参数包为2
  13. func(1,'A',"hello world");//三个参数,参数包为3
  14. return 0;
  15. }

        运行结果:

        此处注意计算参数包的写法。 

结语 

        以上就是关于可变参数模板的讲解,比如当我们不知道要传多少个参数给到模板时,这类场景下就可以使用可变参数模板了,该模板参数可以接收任意数量个参数,然后再用特殊的写法将其内容展开就可以读取到参数包里的数据了。

        最后希望本文可以给你带来更多的收获,如果本文对你起到了帮助,希望可以动动小指头帮忙点赞

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/不正经/article/detail/576952
推荐阅读
相关标签