¿Puede un operador de reparto ser explícito?

84

Cuando se trata de constructores, agregar la palabra clave explicitevita que un compilador entusiasta cree un objeto cuando no era la primera intención del programador. ¿Este mecanismo también está disponible para los operadores de casting?

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

Aquí, por ejemplo, me gustaría poder convertir Fooen un std::string, pero no quiero que ese lanzamiento suceda implícitamente.

qdii
fuente

Respuestas:

101

Si y no.

Depende de la versión de C ++ que estés usando.

  • C ++ 98 y C ++ 03 no admiten explicitoperadores de conversión de tipos
  • Pero C ++ 11 lo hace.

Ejemplo,

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 
}

Compílelo con g++ -std=c++0x, obtendrá este error:

prog.cpp: 13:20: error: conversión de 'A' a tipo no escalar 'std :: string' solicitada

Demostración en línea: http://ideone.com/DJut1

Pero tan pronto como escribas:

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

El error desaparece: http://ideone.com/LhuFd

Por cierto, en C ++ 11, el operador de conversión explícito se denomina "operador de conversión contextual" si se convierte en booleano . Además, si desea obtener más información sobre las conversiones implícitas y explícitas, lea este tema:

Espero que ayude.

Nawaz
fuente
9
Incluso en C ++ 03, es fácil evitar la conversión implícita. Simplemente llame a la función toString, en lugar de operator std::string. Por supuesto, esto puede causar problemas con algunas plantillas. Siempre lo he usado toStringy nunca me ha causado ningún problema, pero imagino que esto podría depender de su estilo de codificación.
James Kanze
@MatthieuM. Como operator std::string():-).
James Kanze
2
Yo uso to_stringen su lugar. Ayuda que sea lo que C ++ 11 lo llama, por lo que ayuda a escribir código compatible con versiones posteriores y ayuda con las plantillas.
Luis Machuca
1
std::string s(a)o std::string s{a}también debería funcionar como static_cast<std::string>(a).
alfC
2
@Bin: porque el compilador explicit operator bool() invoca contextualmente cuando escribe if(std::cin). Tenga en cuenta que la conversión que se produce aquí se denomina (informalmente) conversión contextual , no conversión implícita .
Nawaz