2016-02-11 33 views
7

Chcę napisać lambdę, która przyjmuje dowolną liczbę argumentów za pomocą odwołania uniwersalnego i całkowicie je ignoruje. Oczywisty sposób byłoby użyć składni o zmiennej liczbie argumentów uniwersalnego parametrów paczki i pominąć nazwę parametru:Jak napisać ogólną lambdę wariadową, która odrzuca jej parametry?

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

To działa prawidłowo (z gcc 4.9.2) aż 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 '...' 

Co dziać się? Czy mój kod jest źle sformułowany, czy jest to błąd w gcc?

W obu przypadkach, jakie jest najlepsze obejście tego problemu? Okazało się, że nazywanie parametr działa, ale potem wpadłem na ostrzeżenia nieużywany parametrach:

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] 

Jak tłumić ostrzeżenie niewykorzystane-parametru na opakowaniu parametr szablonu?

+3

To wygląda jak błąd GCC. To [działa] (http://coliru.stacked-crooked.com/a/e1b37f5289b7c8ec) w wersji 5.2. – TartanLlama

+0

@TartanLlama Dla pewnej definicji "dzieła". 5.2 obsługuje przekazywanie obiektów, które nie mogą być kopiowane przez '...', ale błąd parsowania nie jest poprawiony, IIRC. –

Odpowiedz

10

To jest parsing bug w GCC (co sam zgłosiłeś!). auto&&... jest gramatycznie wieloznaczne i może być analizowany zarówno jako równoważnik auto&&, ... lub zgłoszenia parametr opakowanie (technicznie jest pytanie czy ... jest częścią parametru deklaracja klauzula lub abstrakcyjnych declarator); standard mówi, że należy go analizować jako ten drugi; GCC analizuje ją jako pierwszą.

nazewnictwa pakiet usuwa niejednoznaczność parsowania:

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

tłumić ostrzeżenie, można zastosować __attribute__((__unused__)) (lub, jak sugeruje @Luc Danton, [[gnu::unused]]):

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

lub użyj sizeof...

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

Ponieważ GCC jest wymienione, 'typ var [[gnu :: unused]]' jest alternatywą dla 'type var __attribute __ ((__ unused __))' (zapomniałem z której wersji na). –

+2

@LucDanton i ostatecznie, [[maybe_unused]] '. –