#include <optional>
bool f() {
std::optional<int> opt;
return opt;
}
Kompiliert nicht: 'return': cannot convert from 'std::optional<int>' to 'bool'
Beratungsreferenz Ich hätte gedacht, eine Erklärung zu finden, aber ich habe sie gelesen, da es in Ordnung sein sollte.
Implizite Konvertierungen werden immer dann durchgeführt, wenn ein Ausdruck eines Typs T1 in einem Kontext verwendet wird, der diesen Typ nicht akzeptiert, aber einen anderen Typ T2 akzeptiert. bestimmtes:
- wenn der Ausdruck als Argument beim Aufrufen einer Funktion verwendet wird, die mit T2 als Parameter deklariert ist;
- wenn der Ausdruck als Operand mit einem Operator verwendet wird, der T2 erwartet;
- beim Initialisieren eines neuen Objekts vom Typ T2, einschließlich der return-Anweisung in einer Funktion, die T2 zurückgibt;
- wenn der Ausdruck in einer switch-Anweisung verwendet wird (T2 ist ein integraler Typ);
- wenn der Ausdruck in einer if-Anweisung oder einer Schleife verwendet wird (T2 ist bool).
operator bool()
vonstd::optional
istexplicit
.Antworten:
std::optional
hat keine Möglichkeit zur impliziten Konvertierung inbool
. (Das Zulassen impliziter Konvertierungenbool
wird im Allgemeinen als schlechte Idee angesehen, dabool
es sich um einen integralen Typ handelt, bei dem so etwasint i = opt
kompiliert und völlig falsch gemacht wird.)std::optional
tut eine "kontextbezogene Konvertierung" in bool, deren Definition einem Cast-Operator ähnelt :explicit operator bool()
. Dies kann nicht für implizite Konvertierungen verwendet werden. Dies gilt nur in bestimmten Situationen, in denen der erwartete "Kontext" boolesch ist, wie z. B. die Bedingung einer if-Anweisung.Was du willst ist
opt.has_value()
.quelle
Aus C ++ - Dokumenten :
Lesen Sie mehr über kontextuelle Conversions hier :
Sie können den folgenden Hack ausführen:
weil kontextuelle Umwandlung geschieht im Fall der integrierten in logischen Operatoren, aber Kontext Konvertierung direkt nicht enthält
return
Aussagen undstd::optional
selbst tut nicht hat implizite Konvertierung zubool
.Daher ist es am besten, Folgendes zu verwenden
std::optional<T>::has_value
:quelle
return {opt}
? oderreturn bool{opt};
return {opt};
wird nicht funktionieren, aberreturn static_cast<bool>(opt);
oderreturn bool{opt};
würde funktionieren. Es wird jedoch empfohlen, diehas_value
Member-Funktion zu verwenden, da sie wirklich die klare Absicht zeigt, was Sie tun möchtenreturn !!pot;
Hack (has_value
ist besser)Dies liegt daran, dass die implizite Umwandlung von std :: optional in bool nicht unterstützt wird: https://en.cppreference.com/w/cpp/utility/optional/operator_bool
Sie müssen explizit in bool as konvertieren
bool(opt)
oderopt.has_value()
stattdessen einfach verwenden .quelle
Hier geht es nicht wirklich um implizite Konvertierung, sondern um die Art der Initialisierung.
Was optional ist, ist eine explizite Konvertierungsfunktion, dh
Von N4849 [class.conv.fct] / p2
Das Obige bedeutet, dass diese Fälle die Konvertierungsfunktion verwenden: [dcl.init] / p16
In diesen Fällen wird jedoch die Konvertierungsfunktion nicht verwendet: [dcl.init] / p15
Das Beispiel in der Frage fällt unter den Fall der Kopierinitialisierung und verwendet nicht die Konvertierungsfunktion von optional.
quelle