2010-05-05 5 views
5

Mentre sperimentavo un po 'con i template C++ sono riuscito a produrre questo semplice codice, per il quale l'output è diverso, di quanto mi aspettassi secondo le mie conoscenze sulle regole del C++.Ricerca del nome per nomi non dipendenti dal parametro del modello in VC++ 2008 Express. E 'un errore?

void bar(double d) 
{ 
    std::cout << "bar(double) function called" << std::endl; 
} 

template <typename T> void foo(T t) 
{ 
    bar(3); 
} 

void bar(int i) 
{ 
    std::cout << "bar(int) function called" << std::endl; 
} 

int main() 
{ 
    foo(3); 
    return 0; 
} 

Quando compilo questo codice in VC++ 2008 Express, la funzione viene chiamata bar(int). Questo sarebbe il comportamento, mi aspetterei se il bar(3); nel corpo del modello dipendesse dal parametro del modello. Ma non lo è. La regola che ho trovato here dice "Lo standard C++ prescrive che tutti i nomi che non dipendono dai parametri del modello siano associati alle loro definizioni attuali quando analizzano una funzione o una classe template". Ho torto, che la "definizione attuale" di bar quando si analizza la funzione modello foo è la definizione di void bar(double d);? Perché non è il caso se mi sbaglio. Non ci sono dichiarazioni anticipate di bar in questa unità di compilazione.

+0

Non sarebbe sorpreso se hai ragione. Mi sembra che l'implementazione di modelli di VC++ ignori completamente i problemi dipendenti/non dipendenti. – UncleBens

+1

VC++ non ha mai rispettato la valutazione standard di 2 passaggi (il primo durante la lettura della definizione del modello e il secondo nell'istanza del modello). Salva dei caratteri 'typename' e' template' in alcuni punti ma ... non è conforme. –

+0

Per motivi di precisione si fa riferimento alla sezione 14.6.3 Nomi non dipendenti [temp.nondep] dello standard. (Draft finale) – Francesco

risposta

3

In effetti è un bug nel compilatore. Il problema era noto esistere in VS2005 e prima (io uso un blog Blogspot come un notebook per casi come questo, vedi 1.3 here). Apparentemente è presente anche in VS2008.

È possibile verificare con il seguente codice semplice

int bar(double d) { return 0; } 

template <typename T> void foo(T t) { 
    int i = bar(3); 
} 

void bar(int i); 

int main() { 
    foo(3); 
} 

Questo codice è ben formato (è possibile compilare con Comeau in linea del compilatore), ma scommetto che VS sarà soffocare su di esso, perché VS implementa il ricerca in due fasi non corretta in questo caso.

+0

Yup, VS (beh, almeno la mia versione Express, ma penso che sia lo stesso compilatore in altri) afferma che ci sono errori nel codice. Grazie. –

+0

questo errore si presenta ancora su Visual Studio 2010. – smerlin

2

AndreyT è corretto. In effetti, il tuo codice è praticamente identico a un esempio dello standard (§14.6.3/1):

void g(double); 
void h(); 

template<class T> class Z { 
public: 
    void f() { 
     g(1); //calls g(double) 
     h++;  //ill-formed: cannot increment function; 
       // this could be diagnosed either here or 
       // at the point of instantiation 
    } 
}; 

void g(int);  // not in scope at the point of the template 
       // definition, not considered for the call g(1) 
Problemi correlati