How to write a generic variational lambda that discards its parameters?

I want to write a lambda that takes an arbitrary number of arguments with a universal reference and completely ignores them. An obvious method would be to use the syntax for a variable universal parameter package and omit the parameter name:

auto my_lambda = [](auto&&...) { return 42; }; 

This works fine (with gcc 4.9.2) until I try to pass in an object not subject to trivial copying :

 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 happening? Is my code badly formed, or is this a bug in gcc?

Anyway, what's the best workaround? I found that parameter naming works, but then I came across a warning about an unused parameter:

 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 a warning about an unused parameter in the template parameters package?

+7
c ++ lambda c ++ 14 variadic
source share
1 answer

This is a bug in the GCC (which you yourself reported!). auto&&... is grammatically ambiguous and can be parsed as the equivalent of auto&&, ... or a parameter package declaration (technically the question is whether ... part of a parameter-declaration-parameter or an abstract-declarator); the standard says that it is parsed as the last; GCC analyzes it as the first.

Package naming removes the ambiguity of parsing:

 auto my_lambda = [](auto&&... unused) { return 42; }; 

To suppress the warning, you can use __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; }; 
+10
source share

All Articles