Ich frage mich, ob es möglich ist, eine Funktion zu schreiben, die eine Lambda-Funktion in C ++ 11 zurückgibt. Ein Problem ist natürlich, wie eine solche Funktion deklariert wird. Jedes Lambda hat einen Typ, aber dieser Typ ist in C ++ nicht ausdrückbar. Ich denke nicht, dass das funktionieren würde:
auto retFun() -> decltype ([](int x) -> int)
{
return [](int x) { return x; }
}
Noch dies:
int(int) retFun();
Mir sind keine automatischen Konvertierungen von Lambdas in Zeiger auf Funktionen oder ähnliches bekannt. Ist die einzige Lösung, die ein Funktionsobjekt handgefertigt und zurückgibt?
decltype
nicht das gleiche wie im Funktionskörper ist und daher einen anderen Typ hat (auch wenn Sie die return-Anweisung enthalten haben)decltype([](){})
odersizeof([]() {})
ist schlecht geformt, egal wo du es schreibst.Antworten:
Sie benötigen kein handgefertigtes Funktionsobjekt, sondern verwenden es einfach
std::function
, in das Lambda-Funktionen konvertierbar sind:Dieses Beispiel gibt die Ganzzahlidentitätsfunktion zurück:
quelle
std::function
.std::function
Typlöschung verwendet wird, was die Kosten für einen virtuellen Funktionsaufruf beim Aufrufen von bedeuten kannstd::function
. Beachten Sie, ob die zurückgegebene Funktion in einer engen inneren Schleife oder in einem anderen Kontext verwendet wird, in dem die leichte Ineffizienz von Bedeutung ist.Für dieses einfache Beispiel brauchen Sie nicht
std::function
.Aus dem Standard §5.1.2 / 6:
Da Ihre Funktion keine Erfassung hat, bedeutet dies, dass das Lambda in einen Zeiger auf eine Funktion vom Typ konvertiert werden kann
int (*)(int)
:Das ist mein Verständnis, korrigiere mich, wenn ich falsch liege.
quelle
Sie können die Lambda-Funktion von einer anderen Lambda-Funktion zurückgeben, da Sie den Rückgabetyp der Lambda-Funktion nicht explizit angeben sollten. Schreiben Sie einfach so etwas im globalen Bereich:
quelle
Obwohl die Frage speziell nach C ++ 11 fragt, erlaubt C ++ 14 für andere, die darauf stoßen und Zugriff auf einen C ++ 14-Compiler haben, jetzt abgeleitete Rückgabetypen für normale Funktionen. Das Beispiel in der Frage kann also so angepasst werden, dass es wie gewünscht funktioniert, indem einfach die
-> decltype
Klausel ... nach der Liste der Funktionsparameter gelöscht wird:Beachten Sie jedoch, dass dies nicht funktioniert, wenn mehr als eine
return <lambda>;
in der Funktion angezeigt wird. Dies liegt daran, dass eine Einschränkung beim Abzug von Rückgabetypen darin besteht, dass alle Rückgabeanweisungen Ausdrücke desselben Typs zurückgeben müssen, aber jedes Lambda-Objekt vom Compiler einen eigenen eindeutigen Typ erhält, sodass diereturn <lambda>;
Ausdrücke jeweils einen anderen Typ haben.quelle
auto retFun() { return [](auto const& x) { return x; }; }
Sie sollten so schreiben:
um Ihre Rückgabe als Funktion zu erhalten und sie wie folgt zu verwenden:
quelle
Wenn Sie nicht über C ++ 11 verfügen und Ihren C ++ - Code beispielsweise auf Mikrocontrollern ausführen. Sie können einen ungültigen Zeiger zurückgeben und dann eine Umwandlung durchführen.
quelle