#include <optional>
bool f() {
std::optional<int> opt;
return opt;
}
Ne compile pas: 'return': cannot convert from 'std::optional<int>' to 'bool'
Consultation de référence J'aurais pensé trouver une explication, mais je l'ai lu comme il se doit.
Des conversions implicites sont effectuées chaque fois qu'une expression d'un certain type T1 est utilisée dans un contexte qui n'accepte pas ce type, mais accepte un autre type T2; en particulier:
- lorsque l'expression est utilisée comme argument lors de l'appel d'une fonction déclarée avec T2 comme paramètre;
- lorsque l'expression est utilisée comme opérande avec un opérateur qui attend T2;
- lors de l'initialisation d'un nouvel objet de type T2, y compris l'instruction return dans une fonction retournant T2;
- lorsque l'expression est utilisée dans une instruction switch (T2 est de type intégral);
- lorsque l'expression est utilisée dans une instruction if ou une boucle (T2 est bool).
operator bool()
destd::optional
estexplicit
.Réponses:
std::optional
n'a aucune possibilité de conversion implicite enbool
. (Autoriser les conversions implicites enbool
est généralement considéré comme une mauvaise idée, car ilbool
s'agit d'un type intégral, donc quelque chose commeint i = opt
cela se compilerait et ferait complètement la mauvaise chose.)std::optional
ne une « conversion contextuelle » bool, dont la définition ressemble à un opérateur de cast:explicit operator bool()
. Cela ne peut pas être utilisé pour les conversions implicites; elle ne s'applique que dans certaines situations spécifiques où le "contexte" attendu est un booléen, comme la condition d'une instruction if.Ce que tu veux c'est
opt.has_value()
.la source
De C + docs :
Découvrez les conversions contextuelles ici :
Vous pouvez faire le hack suivant:
car la conversion contextuelle se produit dans le cas des opérateurs logiques intégrés, mais la conversion contextuelle n'inclut pas d'
return
instructions etstd::optional
n'a pas en soi de conversion implicite versbool
.Par conséquent, il serait préférable d'utiliser
std::optional<T>::has_value
:la source
return {opt}
? oureturn bool{opt};
return {opt};
ne fonctionnera pas , maisreturn static_cast<bool>(opt);
oureturn bool{opt};
ne fonctionnerait. Cependant, il est suggéré d'utiliser lahas_value
fonction membre car elle montre vraiment l'intention claire de ce que vous voulez fairereturn !!pot;
hack (has_value
c'est mieux)En effet, la conversion implicite de std :: facultatif en booléen n'est pas prise en charge: https://en.cppreference.com/w/cpp/utility/optional/operator_bool
Vous devez explicitement convertir en bool as
bool(opt)
ou simplement utiliser à laopt.has_value()
place.la source
Il ne s'agit pas vraiment de conversion implicite, il s'agit du type d'initialisation.
Ce qui est facultatif est une fonction de conversion explicite, c'est-à-dire
Depuis N4849 [class.conv.fct] / p2
Ce qui précède signifie que ces cas utiliseront la fonction de conversion: [dcl.init] / p16
Cependant, ces cas n'utiliseront pas la fonction de conversion: [dcl.init] / p15
L'exemple de la question relève du cas d'initialisation de la copie et n'utilise pas la fonction de conversion facultative.
la source