para - libro de c++ completo
Conversiones implícitas de C++ (4)
Como el consenso parece ser ya: sí, tienes razón.
Pero como esta pregunta / respuesta probablemente se convertirá en el punto de referencia para las conversiones implícitas de C ++ en stackoverflow, me gustaría añadir que para los argumentos de la plantilla las reglas son diferentes.
No se permiten conversiones implícitas para los argumentos que se utilizan para la deducción del argumento de la plantilla. Esto puede parecer bastante obvio, pero no obstante puede conducir a sutiles rarezas.
Case in point, std :: operadores de suma de cuerdas
std::string s;
s += 67; // (1)
s = s + 67; // (2)
(1) compila y funciona bien, el operator+=
es una función miembro, el parámetro de carácter de la plantilla ya se deduce instanciando std::string
para s (a char
). Entonces las conversiones implícitas están permitidas ( int
-> char
), los resultados en s contienen el equivalente de char de 67, por ejemplo, en ASCII esto se convertiría en ''C''
(2) da un error de compilación ya que el operator+
se declara como una función libre y aquí el argumento del carácter de la plantilla se usa en deducción.
Varios comentarios sobre una respuesta reciente mía, ¿Qué otros moldes útiles se pueden utilizar en C ++? Sugieren que mi comprensión de las conversiones en C ++ es defectuosa. Solo para aclarar el problema, considere el siguiente código:
#include <string>
struct A {
A( const std::string & s ) {}
};
void func( const A & a ) {
}
int main() {
func( "one" ); // error
func( A("two") ); // ok
func( std::string("three") ); // ok
}
Mi afirmación fue que la primera llamada de función es un error, porque no hay conversión de un const char * a un A. Hay una conversión de un string a un A, pero usar esto implicaría más de una conversión. Tengo entendido que esto no está permitido, y esto parece ser confirmado por los compiladores de g ++ 4.4.0 y Comeau. Con Comeau, me aparece el siguiente error:
"ComeauTest.c", line 11: error: no suitable constructor exists
to convert from "const char [4]" to "A"
func( "one" ); // error
Si puede señalar dónde estoy equivocado, aquí o en la respuesta original, preferiblemente con referencia al Estándar C ++, hágalo.
Y la respuesta del estándar C ++ parece ser:
Como máximo, una conversión definida por el usuario (constructor o función de conversión) se aplica implícitamente a un único valor.
Gracias a Abhay por proporcionarnos la cita.
Creo que la respuesta de sharptooth es precisa. La sección 12.3.4 del Estándar de C ++ (SC22-N-4411.pdf) titulada ''Conversiones'' deja en claro que solo se permite una conversión implícita definida por el usuario.
1 Las conversiones de tipos de objetos de clase pueden ser especificadas por constructores y por funciones de conversión. Estas conversiones se denominan conversiones definidas por el usuario y se utilizan para las conversiones de tipo implícitas (cláusula 4), para la inicialización (8.5) y para las conversiones de tipo explícitas (5.4, 5.2.9).
2 Las conversiones definidas por el usuario se aplican solo cuando no son ambiguas (10.2, 12.3.2). Las conversiones obedecen a las reglas de control de acceso (Cláusula 11). El control de acceso se aplica después de la resolución de ambigüedad (3.4).
3 [Nota: Consulte 13.3 para una discusión sobre el uso de las conversiones en las llamadas a funciones, así como en los ejemplos a continuación. -Finalizar nota]
4 Como máximo, una conversión definida por el usuario (constructor o función de conversión) se aplica implícitamente a un único valor.
Eso es cierto, solo se permite una conversión implícita .
Se pueden realizar dos conversiones en una fila con una combinación de un operador de conversión y un constructor parametrizado, pero esto causa una advertencia C4927 - "conversión ilegal; más de una conversión definida por el usuario se ha aplicado implícitamente" - en VC ++ por una razón.
El lenguaje de programación C ++ (4th ed.) (Sección 18.4.3) dice que
solo un nivel de conversión implícita definida por el usuario es legal
Esa parte "definida por el usuario" hace que suene como que se pueden permitir múltiples conversiones implícitas si algunas están entre tipos nativos.