2011-04-29 9 views
10

Doubt originated from herefunción de miembro estático de clase elegido sobre la función global con el mismo nombre?


int g() { 
    cout << "In function g()" << endl; 
    return 0; 
} 

class X { 
public: 
    static int g() { 
    cout << "In static member function X::g()" << endl; 
    return 1; 
    } 
}; 

class Y: public X { 
    public: 
    static int i; 
}; 

int Y::i = g(); 

inicialmente I sin embargo, que como símbolo resolución pasa de interior más alcance para más exterior alcance, es por eso que x :: g() sería llamado.
pero luego me di cuenta de cerca el código

int Y::i = g(); 

cómo somos capaces de acceder a X :: g() sin NameScope?
Y el alcance en el que se encuentra esta instrucción debe ser global, no Y :: o X ::, por lo que la resolución del símbolo debe dar la versión global de la función g()?

+1

Si desea que el uso de la función global ':: g()' –

Respuesta

11

Nota: Creo que mi respuesta anterior estaba mal no es Koenig Lookup es decir Argumento dependiente de búsqueda de nombres (ADL) Así que he borrado mi respuesta (anterior), ya que me encontré con la sección correspondiente de la Norma, que responde a su.. pregunta

Su c ode es directamente de la sección §9.4/2 del estándar C++ 03.

Un miembro estático puede ser denominado directamente en el alcance de su clase o en el ámbito de una clase derivada (cláusula 10) de su clase; en este caso , el miembro estático se denomina como si se utiliza una expresión calificado-id, con el anidado de nombre especificador del calificado-id nombrar el ámbito de clase de la que el miembro estático es referencia.

A continuación, facilita este ejemplo (que lo solicitado en la pregunta)

[Example: 

    int g(); 
    struct X { 
     static int g(); 
    }; 
    struct Y : X { 
     static int i; 
    }; 
    int Y::i = g(); // equivalent to Y::g(); 

—end example] 

Se dice entonces que, en el apartado 9.4/3

Si un rotundo-id (5.1) se utiliza en la definición de un miembro estático siguiente declarador-id del miembro, y búsqueda de nombres (3.4.1) encuentra que la sin reservas-id se refiere a un miembro estático, empadronador, o tipo anidado de la clase del miembro (o de una clase base de la clase del miembro), el sin reservas-id se transforma en una expresión calificado-id en la que el nombre-anidado-especificador nombra el clas s ámbito desde el que el miembro es con referencia.

Dado que sucede única en la definición del miembro estático, eso significa Y::g() sólo se llama en el inicialización, no en asignación:

//definition-cum-initialization 
int Y::i = g(); // equivalent to Y::g(); 
int main() 
{ 
    //assignment 
    Y::i = g(); // does not equivalent to Y::g(); it calls global g() 
} 

ver la salida aquí: http://www.ideone.com/6KDMI

Consideremos otro ejemplo:

struct B{}; 

B f(); 

namespace NS 
{ 
    struct A { static B b;}; 
    B f(); 
} 

//Definition cum Initialization 
B NS::A::b = f(); //calls NS::f() 
B b = f();   //calls global f() 

int main() 
{ 
    //Assignment 
    NS::A::b = f(); //calls global f() 
    b = f();  //calls global f() 
} 

Ver la demo completa aquí: http://www.ideone.com/53hoW

+2

aceptado y completamente entendido. En su respuesta anterior, estaba pensando dónde están los argumentos aquí.de todos modos, gracias por informarme sobre Koenig Lookup (nunca lo había oído antes), y por supuesto responder a esta pregunta. – Amar

9

Esto se debe a que usa int Y::i =..., tenga en cuenta Y::. Por eso, en realidad busca g() dentro de Y, que es X::g(), porque Y deriva X.


Adición: Por ejemplo, si se pone int i = g(); después int Y::i = g();, no habría resultado:

In static member function X::g() 
In function g()

EDITAR: exactamente - Argumento dependiente de búsqueda de nombre. No recuerdo cómo se llama esto al principio. respuesta Gracias de Nawaz (:

Edit2: OK, Nawaz encontró la explicación correcta, es en la norma y parece no ser "Argumento dependiente de búsqueda de nombre" Sin embargo, la lógica sigue siendo absolutamente el. . misma

+0

1: a pesar de que Nawaz dio el nombre de la regla, él no identifican claramente que el alcance proviene de 'Y :: i'. –

+0

@Kiril, @Nawaz: Estaba mirando a través de n3242 y no puedo encontrar dónde se precisa que se aplique Koenig Lookup aquí. ** [class.static.data] ** guarda silencio al respecto. Parece extraño (aunque obviamente es lo que está sucediendo) ya que normalmente el tipo de resultado no participa en el proceso de búsqueda y sobrecarga de resolución. ¿Sabrías dónde está? –

+0

@Matthieu M. - No lo siento, lo siento. –

Cuestiones relacionadas