#include <optional>
bool f() {
std::optional<int> opt;
return opt;
}
No compila: 'return': cannot convert from 'std::optional<int>' to 'bool'
Consulta de referencia Pensé encontrar una explicación, pero la leí, ya que debería estar bien.
Las conversiones implícitas se realizan cada vez que se usa una expresión de algún tipo T1 en un contexto que no acepta ese tipo, pero acepta algún otro tipo T2; en particular:
- cuando la expresión se usa como argumento cuando se llama a una función que se declara con T2 como parámetro;
- cuando la expresión se usa como un operando con un operador que espera T2;
- al inicializar un nuevo objeto de tipo T2, incluida la instrucción return en una función que devuelve T2;
- cuando la expresión se usa en una declaración de cambio (T2 es de tipo integral);
- cuando la expresión se usa en una declaración if o un bucle (T2 es bool).
operator bool()
destd::optional
isexplicit
.Respuestas:
std::optional
no tiene ninguna facilidad para convertir implícitamente abool
. (Permitir conversiones implícitasbool
generalmente se considera una mala idea, ya quebool
es un tipo integral, por lo que algo asíint i = opt
se compilaría y haría completamente lo incorrecto).std::optional
no tener una "conversión contextual" a bool, la definición de lo que es similar a un operador de conversión:explicit operator bool()
. Esto no puede usarse para conversiones implícitas; solo se aplica en ciertas situaciones específicas donde el "contexto" esperado es booleano, como la condición de una declaración if.Lo que queremos es
opt.has_value()
.fuente
De documentos de C ++ :
Lea sobre las conversiones contextuales aquí :
Puedes hacer el siguiente truco:
porque la conversión contextual ocurre en el caso de los operadores lógicos integrados, pero la conversión contextual no incluye
return
declaraciones y,std::optional
por sí misma, no tiene conversión implícita abool
.Por lo tanto, sería mejor usar el
std::optional<T>::has_value
:fuente
return {opt}
? oreturn bool{opt};
return {opt};
no va a funcionar, peroreturn static_cast<bool>(opt);
oreturn bool{opt};
funcionaría. Sin embargo, se sugiere utilizar lahas_value
función miembro porque realmente muestra una clara intención de lo que quiere hacerreturn !!pot;
truco (has_value
es mejor)Esto se debe a que la cobertura implícita de std :: opcional para bool no es compatible: https://en.cppreference.com/w/cpp/utility/optional/operator_bool
Debe convertir explícitamente a bool como
bool(opt)
o simplemente usaropt.has_value()
en su lugar.fuente
Esto no se trata realmente de conversión implícita, se trata del tipo de inicialización.
Lo que tiene opcional es una función de conversión explícita, es decir
Desde N4849 [class.conv.fct] / p2
Lo anterior significa que estos casos utilizarán la función de conversión: [dcl.init] / p16
Sin embargo, estos casos no utilizarán la función de conversión: [dcl.init] / p15
El ejemplo en la pregunta corresponde al caso de inicialización de copia y no utiliza la función de conversión opcional.
fuente