2011-02-24 13 views
6

Si quiero utilizar un miembro de una clase base de la plantilla a partir de una clase de plantilla derivada, tengo que ponerla en alcance como tal:C++ utilizando comunicado en su alcance función miembro

template <typename T> 
struct base 
{ 
    void foo(); 
}; 

template <typename T> 
struct derived : base<T> 
{ 
    using base<T>::foo; 
}; 

Por qué no puedo coloque esta instrucción using en un ámbito local, como otras instrucciones using?

template <typename T> 
struct base 
{ 
    void foo(); 
}; 

template <typename T> 
struct derived : base<T> 
{ 
    void f() 
    { 
     using base<T>::foo; // ERROR: base<T> is not a namespace 
    } 
}; 
+1

¿Qué problema está tratando de resolver al hacer esto? ¿Estás tratando de evitar el prefijo 'foo' con' this-> '? –

+2

Al usar la declaración de uso, evito el prefijo 'foo' con' this-> ', yes. Al colocarlo en un ámbito local, estoy tratando de contaminar el alcance derivado solo cuando sea necesario. – HighCommander4

Respuesta

1

El estándar (proyecto 3225) dice en [namespace.udecl]:

Un mediante declaración- para un miembro de la clase será un Miembro-declaración. [Ejemplo:

struct X { 
    int i; 
    static int s; 
}; 
void f() { 
    using X::i; // error: X::i is a class member 
       // and this is not a member declaration. 
    using X::s; // error: X::s is a class member 
       // and this is not a member declaration. 
} 

- ejemplo final]

A usando directiva no tiene tal restricción, sin embargo ([namespace.udir]):

cuando se busca una namespace-name en un using-d irective, solo se consideran nombres de espacios de nombres

+0

Ya veo. Alguna idea acerca de la razón de esto? – HighCommander4

+0

Solo puedo pensar en una cosa: permitirle tener funciones miembro y no miembro en el mismo espacio de búsqueda de nombre, lo que tal vez no pueda suceder bajo las reglas actuales (¿tiene una función miembro por un nombre particular hide namespace? ¿funciones abarcadas por el mismo nombre?). Pero supongo que ADL ya lo haría, así que realmente no tengo idea de por qué. –

2

El propósito de using base<T>::foo en el ámbito de la función es que se desea llamar foo en la función, y ya que da error, no puede hacer eso.

Si desea llamar a la functon (de lo contrario por qué haría eso), entonces usted puede hacer estos que están permitidos:

this->template base<T>::foo(); //syntax 1 
this->base<T>::foo();   //syntax 2 - simple 
this->foo();     //syntax 3 - simpler 

Sin embargo, no puede escribir esto:

foo() ; //error - since foo is in base class template! 
//if you write `using base<T>::foo` at class scope, it will work! 

demo en Ideone: http://www.ideone.com/vfDNs

Lee esto para saber cuando necesidad utilizar template palabra clave en una llamada de función:

Ugly compiler errors with template

+1

I * puede * llamar a 'foo()' sin ninguna calificación si pongo 'using base :: foo' en el alcance de clase en la clase derivada. – HighCommander4

+0

@ HighCommander4: 'utilizando la base :: foo' no es necesario ni siquiera en el ámbito de clase si desea llamar a' foo' desde 'f()'. – Nawaz

+0

Si usar 'this->' es más simple que usar 'usando base :: foo' es una cuestión de preferencia. Solo necesito escribir 'usando base :: foo' una vez, mientras que necesitaría escribir' this-> 'delante de cada llamada a' foo() '. – HighCommander4

Cuestiones relacionadas