I want to write a lambda that takes an arbitrary number of arguments by universal reference and ignores them entirely. The obvious method would be to use the syntax for a variadic universal parameter pack and omit the parameter name:
auto my_lambda = [](auto&&...) { return 42; };
This works fine (with gcc 4.9.2) until I try to pass a non trivially-copyable object:
struct S { S() {} S(S const&) {} };
my_lambda("meow", 42, S{});
^ error: cannot pass objects of non-trivially-copyable type 'struct S' through '...'
What's going on? Is my code ill-formed, or is this a bug in gcc?
In either case, what's the best workaround? I found that naming the parameter works, but then I ran into an unused-parameter warning:
auto my_lambda = [](auto&&... unused) { return 42; };
^ error: unused parameter 'unused#0' [-Werror=unused-parameter]
^ error: unused parameter 'unused#1' [-Werror=unused-parameter]
^ error: unused parameter 'unused#2' [-Werror=unused-parameter]
How do you suppress an unused-parameter warning on a template parameter pack?
It's a parsing bug in GCC (which you yourself reported!). auto&&...
is grammatically ambiguous and can be parsed as either the equivalent of auto&&, ...
or a parameter pack declaration (technically, the question is whether ...
is part of the parameter-declaration-clause or the abstract-declarator); the standard says it's to be parsed as the latter; GCC parses it as the former.
Naming the pack resolves the parsing ambiguity:
auto my_lambda = [](auto&&... unused) { return 42; };
To suppress the warning, one could apply __attribute__((__unused__))
(or, as @Luc Danton suggested, [[gnu::unused]]
):
auto my_lambda = [](auto&&... unused __attribute__((__unused__))) { return 42; };
or use sizeof...
auto my_lambda = [](auto&&... unused) { (void) sizeof...(unused); return 42; };
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With