Um operador de elenco pode ser explícito?

84

Quando se trata de construtores, adicionar a palavra-chave explicitevita que um compilador entusiasmado crie um objeto quando essa não era a primeira intenção do programador. Esse mecanismo também está disponível para operadores de fundição?

struct Foo
{
    operator std::string() const;
};

Aqui, por exemplo, gostaria de ser capaz de lançar Fooem um std::string, mas não quero que tal molde aconteça implicitamente.

qdii
fonte

Respostas:

101

Sim e não.

Depende de qual versão do C ++ você está usando.

  • C ++ 98 e C ++ 03 não suportam explicitoperadores de conversão de tipo
  • Mas C ++ 11 sim.

Exemplo,

struct A
{
    //implicit conversion to int
    operator int() { return 100; }

    //explicit conversion to std::string
    explicit operator std::string() { return "explicit"; } 
};

int main() 
{
   A a;
   int i = a;  //ok - implicit conversion 
   std::string s = a; //error - requires explicit conversion 
}

Compile-o com g++ -std=c++0x, você obterá este erro:

prog.cpp: 13: 20: erro: conversão de 'A' para o tipo não escalar 'std :: string' solicitada

Demonstração online: http://ideone.com/DJut1

Mas assim que você escrever:

std::string s = static_cast<std::string>(a); //ok - explicit conversion 

O erro desaparece: http://ideone.com/LhuFd

BTW, em C ++ 11, o operador de conversão explícita é referido como "operador de conversão contextual" se for convertido para booleano . Além disso, se você deseja saber mais sobre as conversões implícitas e explícitas, leia este tópico:

Espero que ajude.

Nawaz
fonte
9
Mesmo em C ++ 03, é fácil evitar a conversão implícita. Basta chamar a função toString, em vez de operator std::string. Claro, isso pode causar problemas com alguns modelos. Sempre usei toStringe nunca me causou problemas, mas imagino que isso possa depender do seu estilo de codificação.
James Kanze
@MatthieuM. Assim como operator std::string():-).
James Kanze
2
Eu uso em to_stringvez disso. Ajuda que é como o C ++ 11 chama, então ajuda a escrever código compatível com versões futuras e ajuda com modelos.
Luis Machuca
1
std::string s(a)ou std::string s{a}também deve funcionar como static_cast<std::string>(a).
alfC
2
@Bin: Porque o explicit operator bool() é invocado contextualmente pelo compilador quando você escreve if(std::cin). Observe que a conversão que ocorre aqui é (informalmente) chamada de conversão contextual , não de conversão implícita .
Nawaz,