Does C++11 allow the following nested variadic expansion within and of a lambda?

c++, c++11, lambda, variadic-templates

Solution

Yes, this is valid, and Clang supports it.

$ clang++ your-example.cpp -std=c++11
$ ./a.out
MemArgs = 123
Ns = 0variadic_fun(MemArgs...) = 3
MemArgs[Ns] = 1
MemArgs = ABC
Ns = 1variadic_fun(MemArgs...) = 3
MemArgs[Ns] = B
MemArgs = XYZ
Ns = 2variadic_fun(MemArgs...) = 3
MemArgs[Ns] = Z

The relevant rule is [temp.variadic]p5:

An appearance of a name of a parameter pack that is not expanded is ill-formed.

That does not apply in this case, since

A parameter pack whose name appears within the pattern of a pack expansion is expanded by that pack expansion.

... and the uses of the pack within the lambda are within the pattern of the function argument pack expansion.

Problem

Can anyone confirm for me that the following code (which includes nested expansions of a function parameter pack) is allowed in C++11 (I would certainly appreciate any references to the standard): ``` template<class ... VFTs> int variadic_fun(VFTs ... vfts) { return sizeof ...(vfts); } template<int ... Ns> struct IntPack { template<class ... MemTs> static int variadic_memfun(MemTs ... MemArgs) { return variadic_fun(([=]() { cout << "MemArgs = " << MemArgs << "\n"; cout << "Ns = " << Ns; // Note the nested expansion of MemArgs here: cout << "variadic_fun(MemArgs...) = " << variadic_fun(MemArgs ...) << "\n"; cout << "MemArgs[Ns] = " << MemArgs[Ns] << "\n"; return 0; })()...); } }; int main() { IntPack<0, 1, 2>::variadic_memfun("123", "ABC", "XYZ"); } ``` Thanks! P.S. Since someone asked below, this code works with my patch of clang that implements generic lambdas (Not yet standard C++, still just a proposal) - I have not tried it with any other compilers - and am not sure if it works with the latest clang trunk currently (it probably does) - I would certainly welcome any information on whether it compiles with any of the mainstream compilers that implement variadics and lambdas.

Original source