2010-01-31 14 views
22

¿Por qué C++ requiere que el operador de conversión definido por el usuario solo pueda ser miembro no estático? ¿Por qué no está permitido usar funciones independientes como para otros operadores unarios? Algo como esto:operador de conversión como función independiente

operator bool (const std::string& s) { return !s.empty(); } 

Respuesta

6

La única razón que se me ocurre es evitar que las conversiones implícitas se aplican a lo que se está colando. En su ejemplo, si usted dice:

bool("foo"); 

luego "foo" se convertirían implícitamente a una cadena, que tendría entonces la conversión explícita bool que nos ha facilitado que se le aplica.

Esto no es posible si el operador bool es una función miembro, ya que las conversiones implícitas no se aplican a *this. Esto reduce enormemente las posibilidades de ambigüedad: las ambigüedades normalmente se consideran como "cosas malas".

+0

No entiendo su argumento. El ejemplo que proporcionó no es una conversión implícita. Por otro lado, la razón principal para definir un operador de conversión es usar conversión implícita. – shura

+0

@shura Sí lo es. "foo" se convierte implícitamente en una cadena, que luego se convierte explícitamente en bool. He actualizado mi respuesta para aclarar esto. –

+0

Neil, ahora veo tu punto. – shura

0

Al mantener el operador de conversión dentro de la clase, le otorga al autor el control de clase de cómo se puede convertir (Impide a los usuarios crear conversiones implícitas de). Como implementador, lo consideraría una ventaja, ya que implicit conversions does have its issues

Existe una diferencia al poder pasar un objeto como otro y tenerlo pasar por una función de conversión. El primero comunica que el objeto es de un tipo dado, mientras que el último muestra a los lectores nuevos que existe una diferencia entre los dos tipos y que es necesaria una conversión.

+1

No da ningún control adicional. Puedo (y probablemente debería) simplemente escribir una función ToBool() para hacer la conversión. –

+0

También :) La conversión implícita es algo bastante diferente de un ToBool(). Si pudiera haría std :: cadena implícita convertible en un char *, pero afortunadamente Stroustrup et al. sabía mejor – daramarak

-2

Hay un grupo de operadores que deben estar sobrecargados como funciones miembro no estáticas: asignación, suscripción, llamada a función, acceso de miembro de clase, funciones de conversión.

Supongo que el comité de normas o Stroustrup simplemente consideraron que podría ser demasiado confuso si se les permitiera inyectar estos comportamientos muy especiales a las clases externas.


Supongo que la mejor manera de obtener la respuesta sería enviando un correo electrónico al autor.

+0

Um, ¿no se decidió esto mucho antes de que el comité de estándares se conociera por primera vez? – sbi

+0

O tal vez Stroustrup se sintió de esta manera. Esto es meramente una especulación. ¿Qué tienen todos estos en común, entonces todos tienen que ser miembros? No veo ninguna razón técnica, por qué deberían (OK, la asignación tendría un problema técnico, ya que de otra manera el compilador la sintetizaría). – UncleBens

+0

triste porque la conversión de "std :: string" a otras cosas es un deseo común –

-3

Las conversiones implícitas definidas por el usuario están mal vistas de todos modos. No los uses Solo pretenda que no están allí. Y mucho menos pensar en nuevas formas de presentarlos.

De todos modos, supongo que no están allí porque como están pueden hacer suficientes cosas inesperadas. Incluir un nuevo encabezado que introduzca dicha conversión para una clase definida en otro lugar puede generar errores aún más confusos.

+1

+1 aunque diría 's/definido por el usuario //'. –

+0

Entonces, cuando C++ 0x permite el uso de 'explicit' con operadores de transmisión, ¿su argumento aún se mantiene? Pude imaginar alguna utilidad para los operadores independientes de elenco que solo se pueden usar con 'static_cast'. – jamesdlin

+0

No es que sea un gran admirador de las conversiones implícitas definidas por el usuario. No querría convertir implícitamente cadena a bool como en mi ejemplo. Pero a veces son útiles. Tome std :: string (const char *) por ejemplo. – shura

Cuestiones relacionadas