El problema es que el número de conversiones definidas por el usuario que se invoca de forma implícita se limita (a 1) por el estándar.
B ob = a;
implica dos conversiones de usuario:
- en
a
: Wrap<A>::operator A*()
deberían ser llamados
- en el resultado:
B::B(A*)
deberían ser llamados
la explicación de @ James Kanze: este la sintaxis se llama "inicialización de copia", efectivamente equivalente a B ob = B(a)
(sin la copia). Esto es diferente de B ob(a)
que es una "inicialización directa" y habría funcionado.
si califica explícitamente nada de esto, va a trabajar, por ejemplo:
B ob = B(a);
Por otra parte, para el segundo caso no hay ningún problema:
ob = a;
es corto mano para:
ob.operator=(a);
Y, por lo tanto, solo se requiere una conversión definida por el usuario, lo que está permitido.
EDITAR:
ya que ha sido necesario en un comentario (a la respuesta de Kirill) podemos tener una pista sobre el motivo.
conversiones encadenados podrían ser largo, muy largo, y por lo tanto:
- podría sorprender a los usuarios - conversiones implícitas ya que puede ser sorprendente, ya que es ...
- podría conducir a una búsqueda exponencial de las posibilidades (para el compilador) - necesitaría ir desde ambos extremos, tratando de verificar todas las conversiones posibles, y de alguna manera "unir" las dos (con la ruta más corta posible).
Además, siempre que haya más de 1 conversión, correrá el riesgo de tener ciclos, que tendrían que detectarse (aunque el diagnóstico probablemente no sea necesario y estará sujeto a la Calidad de implementación))
Entonces, dado que es necesario un límite para evitar búsquedas infinitamente largas (podría haberse dejado sin especificar, con un mínimo requerido), y dado que más allá de 1 podemos tener nuevos problemas (ciclos), entonces 1 parece un límite como cualquiera después de todo.
¿Qué compilador? Compila bien en VS2010. –
@Agnel Kurian, eso es porque VS2010 tiene un soporte parcial para C++ 0x. –
@Agnel, es con g ++ 4.4.1. – iammilind