以下代码来自《Modern C++ Tutorial: C++11/14/17/20 On the Fly》一书:
template<typename T, typename... Ts> auto printf3(T value, Ts... args) {
std::cout << value << std::endl;
(void) std::initializer_list<T>{([&args] {
std::cout << args << std::endl;
}(), value)...};
}
printf3(1, 2.3, "456");
以下代码的输出是:
1
2.3
456
书中的解释是:
在这段代码中,C++11中提供的初始化列表和 Lambda 表达式的属性(下一节将提到) 另外使用。
通过初始化列表,(lambda 表达式,值)... 将是 扩大了。由于逗号表达式的出现,前面的 首先执行lambda表达式,输出参数 完成了。为了避免编译器警告,我们可以显式转换 std::initializer_list 为 void。
我的问题是,以下似乎不是标准的 lambda 函数,因为 {} 位于 () 之前:
[&args] { std::cout << args << std::endl;} ()
如果我将其更改为以下格式,让 () 位于 {} 之前:
template<typename T, typename... Ts> auto printf3(T value, Ts... args) {
std::cout << value << std::endl;
(void) std::initializer_list<T>{([&args] () {
std::cout << args << std::endl;
}, value)...};
}
结果是:
1
即,args 没有被扩展。这是为什么?
区别在于
[&args] { std::cout << args << std::endl; }()
调用 lambda,而 [&args] () { std::cout << args << std::endl; }
则不调用。
因为没有参数,所以参数列表
()
是可选的。 [&args] () { std::cout << args << std::endl; }()
也会做同样的事情。