2016-02-11 12 views
7

Ich möchte ein Lambda schreiben, das eine beliebige Anzahl von Argumenten durch universelle Referenz akzeptiert und ignoriert sie vollständig. Die offensichtliche Methode wäre die Syntax für ein variadische universelles Parameter Pack zu verwenden und die Parameternamen weglassen:Wie schreibe ich ein generisches Variadisches Lambda, das seine Parameter verwirft?

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

Dies funktioniert gut (mit gcc 4.9.2), bis ich 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 '...' 

Was ist geht es weiter? Ist mein Code schlecht formatiert oder ist das ein Fehler in gcc?

In beiden Fällen ist die beste Problemumgehung? Ich fand, dass der Parameter Benennung funktioniert, aber dann lief ich in eine ungenutzten-Parameter Warnung:

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] 

Wie unterdrücken Sie eine ungenutzten-Parameter Warnung auf einem Template-Parameter Pack?

+3

Das sieht wie ein GCC-Bug aus. Es [funktioniert] (http://coliru.stacked-crooked.com/a/e1b37f5289b7c8ec) in 5.2. – TartanLlama

+0

@TartanLlama Für eine Definition von "funktioniert". 5.2 unterstützt die Übergabe von nicht-trivial kopierbaren Objekten über '...', aber der Parsing-Fehler ist nicht behoben, IIRC. –

Antwort

10

Es ist ein parsing bug in GCC (die Sie selbst gemeldet haben!). auto&&... grammatisch ist mehrdeutig und kann entweder als das Äquivalent von auto&&, ... oder einer Parameterpaket Erklärung analysiert werden (technisch, ist die Frage, ob ... Teil des Parameter-Deklaration-Klausel oder abstract-declarator ist); der Standard sagt, dass es als letzter geparst werden soll; GCC analysiert es als Erstes.

das Pack Naming löst die Parsing Mehrdeutigkeit:

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

die Warnung zu unterdrücken, könnte man anwenden __attribute__((__unused__)) (oder, wie @Luc Danton vorgeschlagen, [[gnu::unused]]):

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

oder sizeof... verwenden

auto my_lambda = [](auto&&... unused) { (void) sizeof...(unused); return 42; }; 
+1

Da GCC erwähnt wird, ist 'type var [[gnu :: unused]]' eine Alternative zu 'type var __attribute __ ((__ unused __))' (Ich vergesse jedoch, ab welcher Version). –

+2

@LucDanton und schließlich, '[[mayable_unused]]'. –