Il problema riscontrato è dovuto al nome delle regole di ricerca per le classi di base dipendenti. 14,6/8 ha:
Quando si cerca per la dichiarazione di un nome usato in una definizione di modello, le regole di ricerca abituali (3.4.1, 3.4.2 ) vengono utilizzati per i nomi nondependent. La ricerca dei nomi che dipendono dai parametri del modello è posticipata fino a quando non si conosce l'argomento del modello effettivo (14.6.2).
(Questo non è proprio "2 fasi di ricerca." - vedi sotto per una spiegazione di quello)
Il punto circa 14,6/8 è che per quanto riguarda il compilatore è interessato NO_ZEROFILL
nel tuo esempio è un identificatore e non dipende dal parametro del modello. Viene quindi esaminato secondo le normali regole di 3.4.1 e 3.4.2.
Questa ricerca normale non esegue la ricerca all'interno di Base<T>
e pertanto NO_ZEROFILL è semplicemente un identificatore non dichiarato. 14.6.2/3 ha:
Nella definizione di un modello di classe o un membro di una classe template, se una classe di base del modello classe dipende da un modello di parametri, nell'ambito di classe base non è esaminata durante ricerca nome non qualificata o al punto di definizione del modello di classe o membro o durante un'istanza del modello di classe o membro.
Quando si qualificano NO_ZEROFILL
con Base<T>::
in sostanza si sta cambiando da essere un nome non dipende in una dipendente e quando lo fai si ritarda la sua ricerca fino a quando il modello viene creata un'istanza.
Nota a margine: Qual è lookup 2 fasi:
void bar (int);
template <typename T>
void foo (T const & t) {
bar (t);
}
namespace NS
{
struct A {};
void bar (A const &);
}
int main()
{
NS::A a;
foo (a);
}
L'esempio precedente è stato compilato come segue. Il compilatore analizza il corpo della funzione di foo
e vede che c'è una chiamata a bar
che ha un argomento dipendente (cioè uno che dipende dal parametro del modello). A questo punto il compilatore cerca la barra come in 3.4.1 e questa è la "ricerca di fase 1". La ricerca troverà la funzione void bar (int)
e verrà memorizzata con la chiamata dipendente fino a un momento successivo.
Quando il modello viene quindi istanziato (come risultato della chiamata da main
), il compilatore esegue quindi una ricerca aggiuntiva nell'ambito dell'argomento, questa è la "ricerca di fase 2". Questo caso che risulta nella ricerca di void NS::bar(A const &)
.
Il compilatore ha due sovraccarichi per bar
e seleziona tra di essi, nel caso precedente chiamando void NS::bar(A const &)
.
aw, mi hai battuto per 20 secondi. +1 – jalf
@jalf: Quindi per una volta, sono il primo. ': ^>' Sentitevi liberi di migliorare. – sbi
Interessante. I membri non statici ereditati richiedono quindi la stessa qualifica? cioè Base :: memberFunction() –
cheshirekow