2017-10-31 16 views
3

Die ISO C++ FAQ (https://isocpp.org/wiki/faq/cpp11-language-templates, "Template-Aliase") zitiert das folgende Beispiel:Alias ​​für eine Lambda-

using P = [](double)->void; // using plus suffix return type 

ich einen Fehler versucht, dies mit g ++ zu kompilieren -std = C++ 11:

error: expected type-specifier before ‘[’ token 

Was sollte die richtige Syntax sein? Wenn ich

auto p = [](double)->void {}; 

tun bekommt p abgeleitet entweder <lambda(double)> oder main()::<lambda(double)> sein, je nach Umfang. Allerdings kann ich nicht dann tun

using P = <lambda(double)>; 

wie auch einen Fehler gibt:

expected type-specifier before ‘<’ token 
+2

Mmmmh, das ist kaputt. – Quentin

+0

Warum brauchen Sie einen Alias ​​für Lambda? Was ist mit einem Funktionszeiger: using FunctionPtr = void (*) (double); –

+0

Keine Antwort, aber 'mit P = std :: function ;' würde wahrscheinlich für Sie arbeiten, da das Lambda in die std :: -Funktion umwandelbar ist. – acraig5075

Antwort

6

Es ist fest! Der aktualisierte Eintrag lautet:

using P = auto (*)(double)->void; 

Nach [expr.prim.lambda], ein Lambda-Ausdruck ist:

lambda-expression: 
    lambda-introducer lambda-declarator[opt] compound-statement 
    lambda-introducer < template-parameter-list > lambda-declarator[opt] compound-statement 

Die Verbindung-Anweisung nicht optional ist, und so [](double)->void ist kein gültiger Lambda-Ausdruck .

[](double)->void {} ist kein Typ und decltype([](double)->void {}) ist schlecht gebildet. Es gibt keinen einfachen Weg, den Typ eines Lambda direkt zu bekommen. Sie können jederzeit eine Abhilfe wie

auto p = [](double) -> void {}; 
using P = decltype(p); 

verwenden, aber ich würde nur Kleben mit Funktionszeigern oder std::function, je nach Anwendungsfall empfehlen, da jedes Lambda eine andere Art hat.

<lambda(double)> ist kein Typ, noch ein Objekt. Es ist nur eine Möglichkeit für Ihren Compiler, auf ein bestimmtes Lambda zu verweisen, es ist überhaupt kein gültiges C++.