2011-08-04 8 views
5

Czy można w jakiś sposób zabronić używania funkcji szablonów dla typów, dla których specjalizacja nie została wyraźnie napisana. Mam na myśli coś takiegoniezespolony szablon bloku C++

template <typename T> 
void foo(){} 

template <> 
void foo<int>(){} 

int main(int argc, char* argv[]){ 
    foo<int>(); //ok 
    foo<char>(); //Wrong - no specialized version for char. 
} 

nie mogę pominąć generyczną wersję funkcji, bo wtedy kompilator mówi, że foo nie jest funkcją szablon gdy próbuję się specjalizować. Mógłbym po prostu napisać coś, co nie kompiluje się w funkcji ogólnej, i dodać komentarz wyjaśniający dlaczego, ale to byłoby dość nieinformacyjne. Chciałbym, aby kompilator działał bezpośrednio z błędem, jak "foo() nie jest zdefiniowane".

Odpowiedz

13

Sure: po prostu nie definiują go i dostaniesz błąd linkera jeśli spróbujesz go używać:

template <typename T> 
void foo(); // not defined 

template <> 
void foo<int>() { } 

Alternatywnie, można użyć jakąś odmianę statycznym assert uzyskując „ładniejszy "błąd kompilacji. Oto przykład użycia C++ 0x static_assert. Zauważ, że musisz ustawić wartość false zależną od parametru szablonu, w przeciwnym razie static_assert może zostać wyzwolony podczas analizy szablonu.

template <typename T> 
struct dependent_false { enum { value = false }; }; 

template <typename T> 
void foo() 
{ 
    static_assert(dependent_false<T>::value, "Oops, you used the primary template"); 
} 

Pamiętaj, że zazwyczaj najlepiej jest not to specialize function templates. Zamiast tego lepiej jest przekazać do specjalistycznego szablonu klasy:

template <typename T> 
struct foo_impl 
{ 
    static_assert(dependent_false<T>::value, "Oops, you used the primary template"); 
}; 

template<> 
struct foo_impl<int> 
{ 
    static void foo() { } 
}; 

template <typename T> 
void foo() 
{ 
    return foo_impl<T>::foo(); 
} 
4

Oczywiście, po prostu nie podawaj definicji domyślnego szablonu ogólnego.