2016-02-23 17 views
6

Mam następujący kod cpp:błąd kompilatora przy użyciu szablonu specjalizacji pod 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; 
} 

Kiedy próbuję skompilować ten przy użyciu programu Visual Studio 2013, pojawia się następujący błąd:

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

Program kompiluje się dobrze, jeśli nie obejmuję specjalizacji foo<float>. Kod również kompiluje dobrze , w tym specjalizację pod gcc 4.8.4, co wskazuje na pewien problem z kompilatorem Visual C++.

Czy kod jest prawidłowy i czy powinien zostać skompilowany? Czy istnieje obejście dla Visual C++?

+0

Mam t ten sam błąd na VS2015, ale kompiluje [tutaj] (http://ideone.com/ttD7BH). –

+0

@Ben: Dobra uwaga. Nie wiedziałem o tej witrynie. Nie mogłem ustalić, którego kompilatora używają, ale ponieważ kompiluje się pomyślnie, zakładam jego gcc. Zastanawia mnie, dlaczego kompiluje się z gcc, ale nie działa z VC++. – dkoerner

Odpowiedz

-1

Zamiast specjalizacji, robię przeciążeń bez "szablonu" słowo kluczowe, tak:

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

void foo(float value) 
{ 
} 

Używam ich w gcc i Visual Studio 2012.

+2

To nie jest specjalizacja. To przeciąża. – NathanOliver

+0

Cóż, jeśli kompilator nie zrobi poprawnie specjalizacji, to przeciążenie wydaje się dobrym sposobem na obejście problemu, który był częścią pierwotnego pytania. –

+0

Zgadzam się, ale * gdy wykonuję specjalizacje, robię je bez słowa kluczowego "szablon", tak jak poniżej: * oznacza, że ​​kiedy wykonujesz specjalizację, używasz płynnego kodu. Informuję, że to wcale nie jest specjalizacja, ale przeciążenie.Możesz napisać to tak: * Zamiast specjalizować szablon, możesz po prostu dodać przeciążenie, które wymaga 'float' * – NathanOliver

3

Pomijając parametr podczas wywoływania foo<float>();, kompilator zamienia się w zagadkę. Kompilator jednocześnie stwierdza, że ​​wyspecjalizowana funkcja jest właściwa do wyboru, ponieważ wyraźnie mówi się o <float> i nie jest tym, ponieważ nie ma parametru. Następnie kompilator osiąga ogólną wersję, ale nie może, ponieważ jest wyspecjalizowany. Nawet HAL9000 nie mógł go znaleźć, chyba że jest zbudowany z gcc. VC++ niepoprawnie obsługuje sytuację. Prawdopodobnie błąd, a nie "według projektu".

Obejście dla Visual C++ jest użycie przeciążenia:

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

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

i nazywają to jak zwykle foo<float>();

+0

Komunikat o błędzie zaobserwowany przez OP jest jednak dziwny. Każdy pomysł, dlaczego pojawi się komunikat "ten konkretny błąd"? – mindriot

+1

Muszę myśleć, że to błąd w analizie funkcji przez MSVS. Clang, g ++ i ICC wszystko kompilują problem OP bez problemu. – NathanOliver

+0

@mindriot Mogę tylko zgadywać, że kompilator sięga po szablon podstawowy, ale nie z "czystym umysłem", więc nie może używać szablonu podstawowego. Nie ma znaczenia, dlaczego ta konkretna wiadomość. To błąd. – Dialecticus

Powiązane problemy