Ich habe mich gefragt, wie ich richtig prüfen soll, ob ein std::function
leer ist. Betrachten Sie dieses Beispiel:
class Test {
std::function<void(int a)> eventFunc;
void registerEvent(std::function<void(int a)> e) {
eventFunc = e;
}
void doSomething() {
...
eventFunc(42);
}
};
Dieser Code wird in MSVC einwandfrei kompiliert, aber wenn ich doSomething()
ohne Initialisierung aufrufe, eventFunc
stürzt der Code offensichtlich ab. Das wird erwartet, aber ich habe mich gefragt, welchen Wert das hat eventFunc
. Der Debugger sagt 'empty'
. Also habe ich das mit einer einfachen if-Anweisung behoben:
void doSomething() {
...
if (eventFunc) {
eventFunc(42);
}
}
Das funktioniert, aber ich frage mich immer noch, welchen Wert nicht initialisiert hat std::function
. Ich würde gerne schreiben if (eventFunc != nullptr)
, std::function
ist aber (offensichtlich) kein Zeiger.
Warum funktioniert das reine wenn? Was ist die Magie dahinter? Und ist es die richtige Art, es zu überprüfen?
c++
c++11
std-function
NightElfik
quelle
quelle
eventFunc
kein Lambda ist. es ist einstd::function
. Sie können Lambdas instd::function
s speichern , aber sie sind nicht dasselbe.Antworten:
Sie suchen nicht nach einem leeren Lambda, sondern danach, ob in dem
std::function
ein aufrufbares Ziel gespeichert ist. Die Prüfung ist genau definiert und funktioniert,std::function::operator bool
wodurch eine implizite Konvertierungbool
in Kontexte ermöglicht wird, in denen boolesche Werte erforderlich sind (z. B. der bedingte Ausdruck in einerif
Anweisung).Außerdem macht die Vorstellung eines leeren Lambda keinen Sinn. Hinter den Kulissen konvertiert der Compiler einen Lambda-Ausdruck in eine
struct
(oderclass
) Definition, wobei die von Ihnen erfassten Variablen als Datenelemente gespeichert werdenstruct
. Es wird auch ein öffentlicher Funktionsaufrufoperator definiert, mit dem Sie das Lambda aufrufen können. Was wäre ein leeres Lambda?Sie können auch schreiben,
if(eventFunc != nullptr)
wenn Sie möchten. Dies entspricht dem Code, den Sie in der Frage haben.std::function
definiertoperator==
undoperator!=
überlastet zum Vergleich mit anullptr_t
.quelle
== nullptr
dasselbe? Es sieht so aus, als ob es eine Überlastung für den==
Bediener geben sollte, die dazu führt, dass ein "Leer"std::function
verglichen wirdtrue
mitnullptr
: cplusplus.com/reference/functional/function/operatorsnullptr
funktioniert auch,if(eventFunc != nullptr)
entsprichtif(eventFunc)
der obigen Frage.std::function::operator bool
erlaubt keine implizite Konvertierung nachbool
. Es ist zwar markiertexplicit
, aber der Standard macht eine Ausnahme für bestimmte Sprachkonstrukte, die boolesche Ausdrücke erwarten, und nennt es "kontextuell in bool konvertiert". Den relevanten Ausschnitt von Standardese und eine Erklärung finden Sie hier: chris-sharpe.blogspot.com/2013/07/…explicit
. Deshalb habe ich sorgfältig angegeben, dass eine implizite Konvertierungbool
in Kontexten möglich ist, in denen boolesche Werte erforderlich sind . Genau das passiert in dem fraglichen Code.Überprüfen Sie hier http://www.cplusplus.com/reference/functional/function/operator_bool/
Beispiel
Ausgabe
quelle
swap()
. Ich dachte, die Ausgabe sei rückwärts, bis ich es merkte.(Lassen Sie mich eine klare Antwort geben.)
Sie können überprüfen, ob a
std::function
mit leer iststd::function::operator bool
.Beispiel
Ausgabe
quelle