2016-02-23 9 views
6

ho il seguente codice cpp:errore del compilatore quando si utilizza modello di specializzazione in Visual C++

#include <iostream> 
#include <limits> 

// C2589 when compiling with specialization, fine when compiling without 
template<typename T> 
void foo(T value = std::numeric_limits<T>::infinity()) 
{ 
} 

// this specialization causes compiler error C2589 above 
template<> 
void foo<float>(float value) 
{ 
} 

int main() 
{ 
    foo<float>(); 
    return 0; 
} 

Quando provo a compilare questo utilizzando Visual Studio 2013, ho il seguente errore:

..\check2\main.cpp(5) : error C2589: '::' : illegal token on right side of '::' 
..\check2\main.cpp(5) : error C2059: syntax error : '::' 

Il programma viene compilato correttamente se non includo la specializzazione foo<float>. Il codice compila anche il valore compresa la specializzazione in gcc 4.8.4, che indica alcuni problemi con il compilatore di Visual C++.

Il codice è corretto e deve essere compilato? C'è una soluzione alternativa per Visual C++?

+0

I have t Lo stesso errore su VS2015, ma compila [qui] (http://ideone.com/ttD7BH). –

+0

@ Ben: buon punto. Non sapevo di questo sito. Non riuscivo a capire quale compilatore usano ma dal momento che si compila con successo presumo il suo gcc. Mi imbarazza perché si compila con gcc ma non riesce con VC++. – dkoerner

risposta

-1

Invece di specializzazioni, faccio sovraccarichi senza la parola chiave "modello", in questo modo:

template<typename T> 
void foo(T value) 
{ 
} 

void foo(float value) 
{ 
} 

Io li uso in gcc e Visual Studio 2012.

+2

Questa non è una specializzazione. Questo è sovraccarico. – NathanOliver

+0

Bene, se il compilatore non esegue correttamente le specializzazioni, l'overloading sembra essere un buon modo per aggirare il problema, che era parte della domanda originale. –

+0

Sono d'accordo ma * Quando faccio specializzazioni, li faccio senza la parola chiave "template", come questa: * significa che quando fai una specializzazione usi il codice che scorre. Vi sto informando che questa non è affatto una specializzazione, ma un sovraccarico.Potresti esprimerlo come * Invece di specializzare il modello puoi aggiungere un sovraccarico che richiede un 'float' * – NathanOliver

3

omettendo il parametro quando si chiama foo<float>(); si sta inserendo il compilatore in un enigma. Compilatore simultaneamente conclude che la funzione specializzata è quella giusta da scegliere perché si dice esplicitamente <float> e non è quella perché non esiste alcun parametro. Il compilatore raggiunge quindi la versione generale, ma non può esserlo perché ce n'è uno specializzato. Anche HAL9000 non è riuscito a capirlo, a meno che non sia stato creato con gcc. VC++ gestisce in modo errato la situazione. Probabilmente un bug, e non "di design".

Soluzione per Visual C++ è quella di utilizzare un sovraccarico:

template<typename T> 
void foo(T value) 
{ 
} 

template<typename T> 
void foo() 
{ 
    foo(std::numeric_limits<T>::infinity()); 
} 

e chiamarlo come al solito foo<float>();

+0

Tuttavia, il messaggio di errore osservato dall'OP è strano. Qualche idea del motivo per cui viene visualizzato _that_ particolare messaggio di errore? – mindriot

+1

Devo pensare che questo sia un bug nell'analisi delle funzioni di MSVS. Clang, g ++ e ICC compilano tutti il ​​problema dell'OP senza problemi. – NathanOliver

+0

@mindriot Posso solo supporre che il compilatore raggiunga il modello base, ma non con la "mente chiara", e quindi non può effettivamente utilizzare il modello base. Non importa davvero perché quel particolare messaggio. È un bug – Dialecticus

Problemi correlati