2009-03-13 13 views
8

¿Me puede decir por qué el código siguiente es que me da el siguiente error - llamado de sobrecarga "C (int)" es ambiguoC++ - Sobrecarga Constructor - privada y pública

yo creo que desde C (char x) es privado, solo el cursor C (flotante) es visible desde el exterior y debe llamarse al convertir int a float.

Pero ese no es el caso.

class C 
{ 
    C(char x) 
    { 
    } 
public: 
    C(float t) 
    { 
    } 
}; 

int main() 
{ 
    C p(0); 
} 

Respuesta

18

Esto se trata en "Effective C++" de Scott Meyer. La razón por la cual esto es ambiguo es que querían asegurarse de que el simple hecho de cambiar la visibilidad de un miembro no cambiara el significado del código ya existente en otra parte.

De lo contrario, supongamos que su clase C estaba en un encabezado en alguna parte. Si tuviera un miembro C (int) privado, el código que presente llamaría C (float). Si, por alguna razón, el miembro C (int) se hizo público, el código anterior llamaría repentinamente a ese miembro, aunque ni el código antiguo ni la función a la que llamaba habían cambiado.

EDIT: Más razones:

Peor aún, supongamos que existen los siguientes 2 funciones:

C A::foo() 
{ 
    return C(1.0); 
} 

C B::bar() 
{ 
    return C(1.0); 
} 

Estas dos funciones se podrían llamar a diferentes funciones dependiendo de si cualquiera foo o la barra fue declarado como amigo de C, o si A o B heredan de él. Tener idéntica llamadas de código diferentes funciones es aterrador.

(Eso es probablemente no tan bien como la discusión puso de Scott Meyer, pero esa es la idea.)

+1

Hmm, esto parecía una gran explicación primero. Pero ... aún es posible crear la clase _sin_un int-ctor, y luego _add_ ese ctor para que el código viejo empiece a llamar al nuevo miembro ... Así que esta protección solo crea una falsa sensación de seguridad. –

+0

Buen punto. Añadiré más. –

7

0 es un tipo int. Dado que se puede convertir implícitamente en flotante o char por igual, la llamada es ambigua. La visibilidad es irrelevante para estos fines.

o bien poner 0.0, 0. o 0.0f, o deshacerse de la C(char) constructor del todo.

Editar: La parte relevante de la norma, la sección 13.3:

3) [...] Sin embargo, una vez que se han identificado las funciones de candidatos y listas de argumentos, la selección de la mejor función es la misma en todos los casos:

  • en primer lugar, un subconjunto de las funciones de los candidatos-que tienen el número correcto de argumentos y cumplen con ciertas otras condiciones, se selecciona para formar un conjunto de funciones viables (13.3.2).
  • Luego, la mejor función viable se selecciona basándose en las secuencias de conversión implícitas (13.3.3.1) necesarias para unir cada argumento con el parámetro correspondiente de cada función viable.

4) Si existe una función viable y única, la resolución de sobrecarga tiene éxito y la produce como resultado. De lo contrario, la resolución de sobrecarga falla y la invocación está mal formada. Cuando la resolución de sobrecarga tiene éxito, y la mejor función viable no es accesible (cláusula 11) en el contexto en el que se utiliza, el programa está mal formado.

Tenga en cuenta que la visibilidad no es parte del proceso de selección.

+0

No mencionó por qué la privacidad no inclina la resolución de sobrecarga. –

+0

+1 esta es la mitad de la historia, pero no aborda la visibilidad –

+0

Cambiando a un voto popular para una cita estándar. –

-1

No creo que:

C p(0); 

se está convirtiendo a:

C(float t) 

es probable que tenga que ver:

C p(0.0f); 
+0

No, ese no es el problema. Existe una conversión implícita de '0' a float * does *. –

Cuestiones relacionadas