C++0x 可变参数包:语法

Posted

技术标签:

【中文标题】C++0x 可变参数包:语法【英文标题】:C++0x Variadic Parameter Pack: Syntax 【发布时间】:2011-10-13 11:28:53 【问题描述】:

以下代码sn-p在gcc4.6.1下无法编译:

template <typename... TS>
void do_stuff(TS... ts)

  auto f = [](TS... things)  ;

它会抛出一个错误,指出包的东西没有展开。但是,以下代码确实可以编译:

template <typename... TS>
void do_stuff(TS... ts)

  auto f = [](TS... things...)  ;

注意参数列表中的东西后面的额外解包运算符。我从未见过在声明期间必须扩展可变参数包的情况。所以我对你们这些好心人的问题是:

这是合法的 C++0x 语法(编译的 sn-p)还是只是 GCC 在处理可变参数类型时的一个怪癖?

【问题讨论】:

这不是“捕获”,捕获发生在[] 括号内。您只是指定一个参数列表。 (但很好的问题!) 谢谢,我编辑了它以使其更有意义。我知道它不是在变量意义上捕获,但似乎 lambda 如何“捕获”类型为 TS 的问题... 啊,我想我找到了答案,是“不”:***.com/questions/3575901/… 但是 lambda 函数本身没有模板化。当需要评估 lambda 表达式时,这些类型将被很好地定义。 嗯,对,忽略那条评论。其实你好像也可以说doStuff(TS... ts...)。我不知道(TS... ts) 是不是允许成员函数声明的简写... 【参考方案1】:

两件事:

是的,GCC 拒绝[](TS... things) 是错误的。它可能尚未实施。 [](TS ... things...) 声明的内容等同于[](TS... things, ...)。在 C++(不是 C)中,您可以在 C 风格的可变参数省略号之前去掉逗号。所以你可以声明void printf(char const *fmt...),而不是void printf(char const *fmt, ...)。这就是您的 lambda 中发生的情况。第一个省略号是参数包解包,第二个省略号是 C 风格的可变参数省略号。

【讨论】:

很高兴知道,但是如果我调用m(1,2); 并打印出12auto m = [](Args... p...) printf("%d%d\n", p...); ; 怎么会在 GCC 4.6 中实际工作? @Kerrek 很难猜测。 -std=c++0x 毕竟被称为实验性支持下一个 C++ 标准。

以上是关于C++0x 可变参数包:语法的主要内容,如果未能解决你的问题,请参考以下文章

C++11 ——— 可变参数模板

c ++ lambdas如何从上层范围捕获可变参数包

可变参数模板

使用可变参数但使用命名参数调用函数的 Scala 语法是啥?

可变参数模板

Frida Hook可变参数