Chinaunix

标题: C++11的可变长参数模板,只能递归的调用吗,能循环吗? [打印本页]

作者: cdsfiui    时间: 2015-11-26 17:22
标题: C++11的可变长参数模板,只能递归的调用吗,能循环吗?
在网上看到一些C++11对于variadic template的介绍,给出的示例代码都是下面这样的递归调用:

  1. template<typename T>
  2. void output(T&& value)
  3. {
  4.     cout << value << endl;
  5. }
  6. template<typename First, typename... Rest>
  7. void output(First&& first, Rest&&... rest)
  8. {
  9.     cout << first << ",";
  10.     output(forward<Rest>(rest)...);
  11. }
复制代码
可是我不想递归,就像类似C的va_list那样,有个循环来迭代访问所有的参数。
能做到吗?
谢谢。
作者: lost_templar    时间: 2015-11-26 17:28
能,用 sizeof... 做循环

虽然循环跟递归没有区别
作者: cdsfiui    时间: 2015-11-27 18:00
lost_templar 发表于 2015-11-26 17:28
能,用 sizeof... 做循环

虽然循环跟递归没有区别


用sizeof...得到了长度以后,如何挨个得到参数列表里面的项呢? 下标似乎不行啊,我试了。
作者: lost_templar    时间: 2015-11-27 20:28
cdsfiui 发表于 2015-11-27 18:00
用sizeof...得到了长度以后,如何挨个得到参数列表里面的项呢? 下标似乎不行啊,我试了。


你参考下 boost::mpl::for_each,自己找着葫芦画一下就可以了
作者: lost_templar    时间: 2015-11-27 22:00
cdsfiui 发表于 2015-11-27 18:00
用sizeof...得到了长度以后,如何挨个得到参数列表里面的项呢? 下标似乎不行啊,我试了。


或者直接把参数展开
  1. #include <iostream>
  2. template< typename ... Args  >
  3. auto print( Args ... x )
  4. {
  5.     auto printer = []( auto y ) { std::cout << y << std::endl; };
  6.     auto ans =  { 0, ( printer(x), 0 )..., 0 };
  7.     return ans;
  8. }

  9. int main()
  10. {
  11.     print( 1 );
  12.     print( 1, 1.1, 'a', "abc", true );

  13.     return 0;
  14. }
复制代码
上边代码 c++14 支持,因为我用了 auto

作者: windoze    时间: 2015-11-28 00:04
本帖最后由 windoze 于 2015-11-28 00:04 编辑

我完全充分理解你的需求,所以你应该去用D,因为你已经走上了Andrei的那条邪路…………
话说回来,对一个Type List来说,所谓的“循环”是不存在的,所以从技术上说你只能递归,其实连“递归”都不能算,只能算是嵌套的pattern match。
但由于你这些函数都是template,所以编译器会疯狂做inline优化,所以最终编译出来的代码其实更像是平板,连循环都没有,所以你不用太担心性能问题,需要担心的是大脑保健。
作者: dorodaloo    时间: 2015-11-28 10:10
回复 6# windoze
高手对语言理解这么深刻,
话说回来,
Andrei的那条邪路
怎么个邪法啊 ?
作者: windoze    时间: 2015-11-28 14:54
本帖最后由 windoze 于 2015-11-28 14:55 编辑

回复 7# dorodaloo

type list其实类似于Lisp里的Slist,而且还是immutable的,所以从本质上说要处理它你只能掐头去尾,也就是说一次从头拿出一个元素,剩下的是尾。
这种处理方式谈不上是“递归”还是“循环”,因为它从程序的角度来说根本就不是一个执行过程。
当然因为我们要用一个程序去描述对type list的处理,所以从语法的角度你需要一个表达方式,C++选了pattern match,D选了循环。

你可以看看http://dlang.org/variadic-function-templates.html
这是D的方式
作者: dorodaloo    时间: 2015-11-29 13:18
回复 8# windoze

自己对语言的理解一窍不通。
非常感谢高手这么深刻的剖析!




欢迎光临 Chinaunix (http://bbs.chinaunix.net/) Powered by Discuz! X3.2