2013-05-03 14 views
13

Betrachten Sie die folgende Funktion, die eine Lambda zurückkehrt:Zurückgeben eines Lambda ohne std :: function

std::function<int()> make_counter() 
{ 
    int i = 0; 
    return [=]() mutable { return i++; }; 
} 

Ist es möglich, die tatsächliche Lambda-Typ zurück, ohne sie in eine std::function Verpackung?

Antwort

18

C++ 11: Nein, jeder Lambda-Ausdruck hat, ich zitiere (§5.1.2/3):

[...] eine einzigartige, unbenannte nicht gewerkschaftlich Klassentyp [ ...]

Dies bedeutet effektiv, dass Sie den Lambda-Typ nicht kennen können, ohne zuerst den entsprechenden Ausdruck zu kennen.

Nun, wenn Sie nichts erfasst haben, könnten Sie die Konvertierung zum Funktionszeiger verwenden und das zurückgeben (ein Funktionszeigertyp), aber das ist ziemlich einschränkend.

Wie @Luc bemerkt in der Lounge, wenn Sie bereit sind, Ihre make_counter zu ersetzen (und wenn es nicht eine Vorlage oder überlastet, oder etwas ist), würde die folgende Arbeit:

auto const make_counter = [](int i = 0) { 
    return [i]() mutable { return i++; }; 
}; 

C++ 1y: Ja, durch Rückgabebetrag für normale Funktionen (N3582).

+1

Dieser Lambda-Ausdruck ist auch nicht C++ 11 gültig. Der Rückgabetypabzug würde nicht funktionieren, wenn der Body mehr als nur den 'return expression;' (§5.1.2,4) enthält –

+0

Technisch könnte man 'my_not_STD_function' zurückgeben, das einfach etwas im Wesentlichen Äquivalentes wiederimplementiert ... – Yakk

+1

@Arne: Schuld OP zum Bearbeiten ...: P Fixed. – Xeo

10

Wenn Sie schummeln und Rückgabetyp Abzug verwenden, yes you can (Link).

Beachten Sie, dass dies nur nach C++ 11 selbst möglich ist, obwohl es in regulären, nicht warnenden C++ 11 mit Lambda (dh einem Lambda innerhalb eines Lambda, das diese Lambda zurückgibt) durchgeführt werden kann. .

+0

Nicht C++ 11, nicht (noch) Standard. – Xeo

+0

Ja, C++ ist immer noch langsam. = [ –

+0

@Fred siehe den Link erneut, und achten Sie auf die Befehlszeile zum Kompilieren. –

Verwandte Themen