2012-01-28 25 views
10
void foo(int) 
{ 
} 

class X 
{ 
    void foo() 
    { 
    } 

    void bar() 
    { 
     foo(42); 
     // error: no matching function for call to 'X::foo(int)' 
     // note: candidate is: 
     // note: void X::foo() 
     // note: candidate expects 0 arguments, 1 provided   
    } 
}; 

¿Por qué C++ no puede llamar a la función gratuita (que es la única con la firma correcta)?función miembro que oculta la función libre

+2

En este caso, puede usar ':: foo (42)' para acceder al foo externo. [Demo de Ideone] (http://ideone.com/6HljO). Pero no sé mucho sobre espacios de nombres. –

+0

Considero que es un talón de Aquiles de C++. Hace imposible el uso elegante de nombres de funciones libres sobrecargados comunes, como isempty (thing), donde hay muchas sobrecargas para tipos de cosas vacíos, al tiempo que permite que también exista thing.isempty(). Estúpido, desafortunado, torpe. – Mordachai

Respuesta

5

La razón lógica es consistencia.

  • Supongamos según la sugerencia, compilador resuelve foo(42) a ::foo(int).
  • Ahora después de algún tiempo, si cambia X::foo() a X::foo(int) entonces foo(42) se resolverá en X::foo(int). Lo cual no es consistente.

Esa es la razón por la cual la función de clase derivada oculta la función de clase base cuando hay nombres similares.

Tales casos se pueden resolver de 2 maneras;

(1) Dar nombre completo (por ejemplo ::foo(42))

(2) Usar using utilidad; p.ej.

void bar() 
{ 
    using ::foo; 
    foo(42); 
} 
+1

Si alguien más tarde agrega foo (int) miembro, entonces están explícitamente con la intención de esto. Diseño de lenguaje incorrecto, IMO. – Mordachai

12

Porque los dos identificadores se definen en diferentes ámbitos, y la resolución de sobrecarga solo se refiere a las funciones en el mismo ámbito. Una vez que el compilador encuentra que la clase tiene un foo, deja de ascender a ámbitos más amplios (C++ 11 §3.4.1/1), por lo que la función gratuita foo está oculta.

Es necesario utilizar un nombre calificado para referirse a lo global foo:

::foo(42); 
+1

Nota: este es un caso específico debido a 'int', la mayoría de las veces funciona porque ADL es bueno. –

0

no puede responder a la razón por la parte de su pregunta - No sé cuál era la razón de que en la especificación idioma .

Para llamar a la función global en su ejemplo, utilizar el :: sintaxis:

::foo(42); 
0

La razón de esto es el hecho, que el compilador buscará un nombre de función de emparejamiento en primer lugar, haciendo caso omiso de los valores de retorno y parámetros. Cuando esté dentro de una clase, tratará de buscar un miembro que coincida (de hecho, examinará todos los ámbitos que van "hacia arriba", alcance (s) local, alcance de la función, alcance de clase, alcance del espacio de nombres, alcance global, etc.)

X::foo es el primer nombre que coincide. ENTONCES (no antes) intentará elegir la sobrecarga correcta (si hay varias declaraciones) basada en los parámetros (que es la razón por la que puede sobrecargar la misma función con diferentes parámetros pero no con valores de retorno diferentes) y luego comprobará el valor de retorno (si hay alguno).

1

Me gusta su pregunta.Yo también podría decir, utilice esta sintaxis:

::foo(42); 

Pero puedo decir que en mi opinión es elegante y buena programación más, espacios de nombres establecidos, por lo que puede escribir algo como esto:

namespace MyNameSpace 
{ 
    void foo(int){} 

    class X 
    { 
     void foo(){} 

     void bar() 
     { 
      MyNameSpace::foo(42); 
     } 
    }; 
}; 

Este es una buena cosa porque Namespaces permite agrupar clases, objetos y funciones bajo un nombre.

PS: Luego, esto le ayudará a comprender el significado de escribir ::foo(42); cuando no tenga ningún espacio de nombre.

2

Un nombre en un ámbito interior oculta los nombres en ámbitos externos. No importa si se trata de una función u otra cosa, o si estás en una clase o en un espacio de nombres.

Solo si la búsqueda de nombre encuentra varias funciones con el mismo nombre, se iniciará la resolución de sobrecarga para tratar de seleccionar la que mejor se adapte a la llamada.

Cuestiones relacionadas