2014-07-23 14 views
5

Il seguente codice compila in Visual C++ 2013, ma non sotto G ++ 4.8.2:Elaborazione di funzioni template istanziati

template<class T> 
int MyFunc(T& t) 
{ 
    return static_cast<int>(CCodes::blah); 
} 

template<> 
int MyFunc(float& t) 
{ 
    return 0; 
} 

int main() { 
    float f = 10.f; 
    return MyFunc(f); 
} 

Visual C++ sembra ignorare la funzione generale del modello, perché solo la specializzazione MyFunc<float> viene utilizzato. G ++ analizza comunque la funzione generale e rileva che l'enumerazione CCodes non è stata definita.

Quale è giusto? O è questa implementazione definita?

+0

In entrambi i casi, il codice non valido è ancora codice malformato. –

+0

Quindi immagino che la mia domanda possa essere riformulata: questo codice è malformato? O il compilatore è autorizzato a non analizzare definizioni di modelli non confermate? – Tom

+0

@Tom Cosa succede se scrivi 'return static_cast (CCodes :: blah);'? –

risposta

6

GCC è corretto e ogni altro compilatore oltre a MSVC farà la stessa cosa.

Questo è un bug grave, che in realtà è apparso su una roadmap futura di MSVC. Era nella categoria del "lontano futuro". Dovranno riscrivere il loro motore di template per risolverlo.

C'è una linea di argomentazione che la diagnosi di un modello mal formato è facoltativa, perché è davvero un modello senza un'istanza ben strutturata e non è necessario contrassegnarlo. Tuttavia,

  1. Lo standard richiede l'analisi del modello e la mancata analisi deve essere diagnosticata indipendentemente dall'istanza.
  2. Ogni altro compilatore fa la diagnosi, quindi in effetti non farlo porta gli utenti di MSVC a produrre codice non trasportabile. Lamentarsi è davvero una buona idea, anche se non è richiesto.
+0

Hmm, §14.6 [temp.res]/p10 dice "Se un nome non dipende da un parametro di modello (come definito in 14.6.2), una dichiarazione (o un insieme di dichiarazioni) per tale nome deve essere il punto in cui il nome appare nella definizione del modello ". A differenza della regola generale "nessuna specializzazione valida", non vi è alcuna "richiesta di diagnostica necessaria". –

+0

@ T.C. Destra. Poiché C++ è una grammatica sensibile al contesto (non contestualizzata), la ricerca del nome deve essere eseguita come parte dell'analisi. Questo è parte di ciò che intendevo per (1). – Potatoswatter

+0

In realtà la situazione è un po 'peggiore di quella - puoi letteralmente mettere quasi tutta la spazzatura nel corpo di una funzione di modello non definita e il compilatore VC++ la ignorerà. Finché non contiene la parentesi di chiusura e non stravolge il preprocessore, sembra che non importi. – Tom

Problemi correlati