7

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?

ildjarn
  • 62,044
  • 9
  • 127
  • 211
ecatmur
  • 152,476
  • 27
  • 293
  • 366
  • 3
    That looks like a GCC bug. It [works](http://coliru.stacked-crooked.com/a/e1b37f5289b7c8ec) in 5.2. – TartanLlama Feb 11 '16 at 10:04
  • @TartanLlama For some definition of "works". 5.2 supports passing non-trivially-copyable objects through `...`, but the parsing bug isn't fixed, IIRC. – T.C. Feb 11 '16 at 13:41

1 Answers1

10

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; };
T.C.
  • 133,968
  • 17
  • 288
  • 421
  • 1
    Since GCC is mentioned, `type var [[gnu::unused]]` is an alternative to `type var __attribute__((__unused__))` (I forget from which version on though). – Luc Danton Feb 11 '16 at 13:59
  • 2
    @LucDanton and eventually, `[[maybe_unused]]`. – T.C. Feb 11 '16 at 14:00