2016-10-09 31 views
23

Eksperymentowałem z lambdami i kompilatorami z powodu another question tutaj na SO.
Właśnie sobie sprawę (i to jest rzeczywiście całkowicie normalne), że następujący kod jest ważny:Czy [] <typename>() {} ma poprawną definicję lambda?

int main() { 
    auto l = [](){}; 
    l.operator()(); 
} 

Faktycznie średnia mówi, że rodzaju zamknięcie ma wbudowany publiczny operator wywołania funkcji i tak dalej, a tym samym ma sens, aby móc go przywołać.

Nie mogę wyjaśnić, patrząc na standardzie (dobrze, projekt roboczy) jest fakt, że GCC (6,1) kompiluje się następujący fragment (dzyń 3.9 nie robi):

int main() { 
    auto l = []<typename>(){}; 
    l.operator()<void>(); 
} 

żadne ostrzeżenia , bez błędów. Czy jest to poprawny kod, czy powinien zostać odrzucony przez kompilator?

+0

[Opracowanie z powodzeniem] (http://cpp.sh/4asuj) – amanuel2

+1

@ amanuel2 wiem, że kompiluje (GCC przynajmniej), ale pytanie brzmi, czy jest ważne, czy nie. – skypjack

+1

C++ 14 pozwoli na "szablonowe" lambdy, ale jest to ze słowem kluczowym 'auto' zamiast ze składnią szablonu' <> '(zobacz https://stackoverflow.com/questions/3575901/can-lambda-functions-be - rozważany).Może programiści GCC chcieli eksperymentować z różnymi sposobami dodawania tego rodzaju funkcjonalności? –

Odpowiedz

21

W N4140 5.1.2 [expr.prim.lambda] wyrażenie N określa się jako

lambda wprowadzający lambda declarator opcjonalnie związek instrukcja_select

gdzie "Wprowadzający lambdę" jest [], obejmujący opcjonalny "przechwytywanie lambda" i "deklarator lambda opt " to rzeczy zaczynające się od " (parametr-deklaracja-klauzula) ".

[]<typename>(){} 

nie spełnia tego wymogu, ponieważ nie jest czymś pomiędzy wprowadzającego lambda i declarator lambda, więc nie jest to poprawne wyrażenie lambda.

Twój przykładowy kod jest nieprawidłowy w C++ i powinien zostać odrzucony przez kompilator.


Jak to również oznaczone , kliknąłem przez liście GNU C++ extensions. Nie znalazłem żadnego rozszerzenia, które spowodowałoby, że składnia ta byłaby legalna w GNU C++.

Jednak zgodnie z Sekcją 4 dokumentu nr this proposal (P0428R0), który proponuje dodanie szablonów lambda do C++, gcc uzyskał eksperymentalną implementację wspomnianego dokumentu w 2009 roku. To prawdopodobnie wyjaśnia, dlaczego gcc nie narzeka tutaj.

+4

Biorąc pod uwagę pytanie jest oznaczone GCC, warto sprawdzić, czy istnieje rozszerzenie gnu do normy w tym zakresie. – Vality

+1

@Vality Zgoda, dodano. Dzięki. –

+0

Mam problem z GCC, czy warto o tym wspomnieć? – skypjack

2

Wydaje się być rozszerzeniem GCC (szablony lambdas).

#include <iostream> 

int main() { 
    auto l = []<typename T>(T const& x){ std::cout << __PRETTY_FUNCTION__ << " " << x << std::endl;}; 
    l(42); 
    l("Hello world"); 
} 

skutkuje

main()::<lambda(const T&)> [with T = int] 42 
main()::<lambda(const T&)> [with T = char [12]] Hello world 
+0

Czy możesz podać link do dokumentacji tego? Nie udało mi się go znaleźć i dlatego wykluczyłem możliwość bycia przedłużeniem. Dziękuję Ci. – skypjack

+0

http://gcc.gnu.org/ml/gcc/2009-08/msg00174.html jest najbliżej mogę znaleźć @skypjack – etarion