2011-02-24 20 views
6

Se voglio usare un membro di una classe di base modello da un modello di classe derivata, devo portarlo in ambito come tale:C++ utilizzando dichiarazione nella funzione membro portata

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

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

Perché non è possibile posiziona questa istruzione usando in un ambito locale, come altre istruzioni usando?

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

Quale problema stai cercando di risolvere facendo questo? Stai cercando di evitare il prefisso del nome 'pippo' con' questo-> '? –

+2

Usando la dichiarazione using, sto evitando il prefisso del nome 'pippo' con' this-> ', sì. Inserendolo in un ambito locale, sto cercando di inquinare l'ambito derivato solo dove necessario. – HighCommander4

risposta

1

Lo standard (progetto 3225) dice in [namespace.udecl]:

A dichiarazione using per un membro della classe deve essere un iscrizioni a dichiarazione. [Esempio:

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. 
} 

- esempio fine]

A using-directive non ha tale restrizione, tuttavia ([namespace.udir]):

durante la ricerca di un nome-spazio in un usando-d irettivo, solo i nomi dei nomi dei nomi sono considerati

+0

Capisco. Qualche idea sulla logica alla base di questo? – HighCommander4

+0

Posso solo pensare ad una cosa - che ti permetterebbe di avere funzioni membro e non membro nello stesso spazio di ricerca del nome, che forse non può accadere con le regole attuali (ha una funzione membro con un nome particolare nasconde spazio dei nomi -scopare le funzioni con lo stesso nome?). Ma suppongo che ADL lo farebbe già, quindi non ho idea del perché. –

2

Lo scopo della using base<T>::foo nell'ambito funzione è quella che si desidera chiamare foo nella funzione, e dal momento che dà l'errore, non è possibile farlo.

Se si desidera chiamare il functon (altrimenti perché l'hai fatto), allora si può fare questi che sono autorizzati:

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

Tuttavia, è non si può scrivere questo:

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

Demo in Ideone: http://www.ideone.com/vfDNs

Leggere questo per sapere quando si must utilizzare template parola chiave in una chiamata di funzione:

Ugly compiler errors with template

+1

I * può * chiamare 'foo()' senza alcuna qualifica se metto 'usando la base :: foo' nell'ambito della classe nella classe derivata. – HighCommander4

+0

@ HighCommander4: 'utilizzando la base :: foo' non è necessario nemmeno nell'ambito della classe se si desidera chiamare' pippo' da 'f()'. – Nawaz

+0

L'utilizzo di 'this->' è più semplice dell'uso di 'using base :: foo' è una questione di preferenza. Ho solo bisogno di scrivere 'usando una base :: foo' una volta, mentre dovrei scrivere' this-> 'di fronte a ogni chiamata a' pippo() '. – HighCommander4

Problemi correlati