我认为我的问题是一个极端的案例,你可以用参数包扩展到多远,而且有点难以解释,我想要什么。这个想法最容易用一些代码表达,所以让我们看看以下几行:
// <main.cpp>
#include <tuple>
#include <iostream>
// this function is supposed to return a std::tuple of function objects
// for each template argument type, there should be one such function object,
// that takes a value of this type and returns its half.
template <class... arg_t>
auto make_divide_by_two_lambda_tuple() {
return std::make_tuple(
[](const arg_t& elem) -> arg_t
{
return elem/2;
}...
);
}
int main()
{
// lets initialise a tuple with our function
auto value = make_divide_by_two_lambda_tuple<int, float>();
/*
* If everything workes as planned, the tuple has this structure
* value<0> := [](const int&){ ... }
* value<1> := [](const float&){ ... }
*/
// and we are able to use our functions in the expected way
std::cout << "5/2 (int version) = " << std::get<0>(value)(5) << std::endl;
std::cout << "5/2 (float version) = " << std::get<1>(value)(5) << std::endl;
return 0;
}
对于clang(4.0.1),此示例按照我的预期编译并运行:
$ clang++ -std=c++14 ../main.cpp
$ ./a.out
5/2 (int version) = 2
5/2 (float version) = 2.5
对于g ++(7.1.1),此示例无法编译:
$ g++ -std=c++14 ../main.cpp
../main.cpp: In function ‘auto make_divide_by_two_lambda_tuple()’:
../main.cpp:7:28: error: parameter packs not expanded with ‘...’:
[](const arg_t& elem) -> arg_t
^~~~~
../main.cpp:7:28: note: ‘arg_t’
../main.cpp:7:28: error: parameter packs not expanded with ‘...’:
../main.cpp:7:28: note: ‘arg_t’
../main.cpp:10:4: error: expansion pattern ‘<lambda>’ contains no argument packs
}...
^~~
../main.cpp: In function ‘int main()’:
../main.cpp:15:10: error: ‘void value’ has incomplete type
auto value = make_divide_by_two_lambda_tuple<int, float>();
看来,gcc愿意在lambda表达式的参数列表中使用参数包。但是使用整个lambda对于gcc来说太过分了。
这是使用lambda表达式未定义的行为,还是一个编译器(希望是gcc)错了?
PS:我还检查了docs,但它只解释了,您可以在哪里使用参数包扩展,而不是您可以扩展的哪些参数。