#include <optional>
bool f() {
std::optional<int> opt;
return opt;
}
Não compila: 'return': cannot convert from 'std::optional<int>' to 'bool'
Referência de consultoria Eu teria pensado em encontrar uma explicação, mas li como deveria estar ok.
Conversões implícitas são executadas sempre que uma expressão de algum tipo T1 é usada no contexto que não aceita esse tipo, mas aceita outro tipo T2; em particular:
- quando a expressão é usada como argumento ao chamar uma função que é declarada com T2 como parâmetro;
- quando a expressão é usada como um operando com um operador que espera T2;
- ao inicializar um novo objeto do tipo T2, incluindo a instrução return em uma função retornando T2;
- quando a expressão é usada em uma instrução switch (T2 é do tipo integral);
- quando a expressão é usada em uma instrução if ou em um loop (T2 é booleano).
operator bool()
destd::optional
éexplicit
.Respostas:
std::optional
não tem nenhum recurso para conversão implícita embool
. (Permitir conversões implícitasbool
é geralmente considerado uma má ideia, poisbool
é um tipo integral, portanto, algo comoint i = opt
compilaria e faria completamente a coisa errada.)std::optional
não têm uma "conversão contextual" para bool, cuja definição é semelhante a um operador de conversão:explicit operator bool()
. Isso não pode ser usado para conversões implícitas; aplica-se apenas em determinadas situações específicas em que o "contexto" esperado é booleano, como a condição de uma instrução if.O que você quer é
opt.has_value()
.fonte
Dos documentos C ++ :
Leia sobre conversões contextuais aqui :
Você pode fazer o seguinte hack:
porque a conversão contextual ocorre no caso dos operadores lógicos internos, mas a conversão contextual não inclui
return
instruções e,std::optional
por si só, não tem conversão implícita parabool
.Portanto, seria melhor usar o
std::optional<T>::has_value
:fonte
return {opt}
? oureturn bool{opt};
return {opt};
não funciona, masreturn static_cast<bool>(opt);
oureturn bool{opt};
funcionaria. No entanto, é sugerido o uso dahas_value
função de membro, porque mostra realmente a intenção clara do que você deseja fazer.return !!pot;
hack (has_value
é melhor)Isso ocorre porque a cobertura implícita de std :: optional ao bool não é suportada: https://en.cppreference.com/w/cpp/utility/optional/operator_bool
Você precisa converter explicitamente para bool como
bool(opt)
simplesmente usaropt.has_value()
.fonte
Não se trata realmente de conversão implícita, trata-se do tipo de inicialização.
O opcional tem uma função explícita de conversão, ou seja,
Do N4849 [class.conv.fct] / p2
O exposto acima significa que esses casos usarão a função de conversão: [dcl.init] / p16
No entanto, esses casos não usarão a função de conversão: [dcl.init] / p15
O exemplo na pergunta se enquadra no caso de inicialização da cópia e não usa a função de conversão opcional.
fonte