2014-09-05 4 views
33

Heute habe ich diesen Code"auto" Variable in Lambda in seinem eigenen initializer verwendet

#include <cstdio> 

auto terminal = [](auto term)   
{          
    return [=] (auto func)    
    {         
     return terminal(func(term)); 
    }; 
}; 

Überraschenderweise GCC accepts it. Clang lehnt es ab, weil es terminal in seinem eigenen Initializer verwendet und deklariert wird.

Ich habe den Fehler erwartet, dass der Klang gab, aber ist es wirklich schlecht geformt? Oder muss der Code akzeptiert werden?

+1

Dies scheint polymorphe Lambdas zu verwenden, die ein Merkmal in C++ 14 sind. Überprüfe, ob deine GCC-Version und/oder deine Clang-Version polymorphe Lambdas unterstützt. – YoungJohn

+0

@YoungJohn, Die GCC-Version macht es klar, wenn sie den Code kompiliert. Ich kann mit Zuversicht sagen, dass die Clang-Version auf Coliru beide polymorphe Lambdas unterstützt und den Code nicht kompiliert. – chris

+0

@ YoungJohn danke für Ihre Ratschläge. Ich habe GCC überprüft und es unterstützt polymorphe Lambdas (da es mein Snippet akzeptiert und ausführt). Clang [scheint auch sie zu unterstützen] (http://coliru.stacked-crooked.com/a/e89ece0828ca7484). –

Antwort

15

ich denken dies läuft in §7.1.6.4 [dcl.spec.auto]/p11:

Wenn der Typ eines Unternehmens mit einem undeduced Platzhalterart benötigt wird, um die Art von zu bestimmen, ein Ausdruck, das Programm ist schlecht geformt.

Sie müssen die Art der terminal den Typ der man nicht ableiten, den Typ id-Ausdruckterminal in return terminal(func(term)); (herausgegeben, Hut Spitze @ Richard Smith), aber dieser Ausdruck an dem Punkt, um zu bestimmen, von terminal noch.

+5

Der Rückgabetyp des apply-Operators ist abhängig, es muss nur beim Instanziieren bestimmt werden . – dyp

+4

Sie benötigen den Typ von 'terminal', um den Typ des * id-expressions *' terminal' zu bestimmen, daher ist das Programm schlecht formatiert. –

+1

Danke.Zusammenfassend: Die Spezifikation ist derzeit nicht klar, ob der 'terminal'-Verweis auf die automatische Variable zum Zeitpunkt der Definition der Elementvorlage' operator() 'zurückgewiesen oder bei ihrer Instantiierung akzeptiert werden muss (zu diesem Zeitpunkt ist die Variable nicht mehr) ist "auto"). Die Situation wird von http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#1850 gehandhabt und macht diesen Fall gemäß der Antwort von @ RichardSmith auf std-diskussion schlecht formuliert –