2014-05-21 11 views
8

To pytanie było w wywiadzie: Czy ten kod powoduje błędy kompilacji/łączenia i dlaczego tak jest?Puste nawiasy ostrokątne w definicji szablonu

template <int T> void f(); 
template <> void f<0>() {} 

void test() 
{ 
    f<1>(); 
} 

Proszę wyjaśnić zachowanie. Wielkie dzięki.

+0

Łączenie błąd, trzeba 'szablon void f() {}' – P0W

Odpowiedz

11
template<> void f<0>() {} 

jest specjalizacja szablonu funkcji dla argumentu 0, jeśli zadzwonisz f<0>() ta wersja funkcja zostanie wywołana.

Ten kod jest niepoprawny, powoduje błędy w linkowaniu, ponieważ nie ma specjalizacji dla f<1>, a wersja szablonu funkcji nie jest defined.

+0

Dlaczego oświadczenie zostało pominięte w definicji ? Czy to jest możliwe? – Netherwire

+0

@Netherwire tak, ponieważ jest to specjalizacja, 'szablon <>" wskazuje, że jest to pełna specjalizacja funkcji. – ForEveR

+0

Wielkie dzięki, wspaniałe wyjaśnienie! – Netherwire

0

Zostanie skompilowany, ponieważ kompilator może zobaczyć deklarację dla szablonu ogólnego. Dostępny jest również w pełni wyspecjalizowany szablon dla 0. Ale nazywamy to 1, które spróbuje wywołać ogólny szablon, ale ponieważ linker nie może znaleźć żadnej definicji ogólnego szablonu, program pokaże błąd linkera.

soloution

template <int T> void f(); 
template <> void f<0>() {} 
template <int T> void f() { } 


void test() 
{ 
    f<1>(); 
} 
3

To będzie kompilować (cały kod jest gramatically ważne), ale nie powiedzie się na etapie połączenia.

To dlatego template <int T> void f(); jest zadeklarowany ale nie zdefiniowana, < 0> specjalizacja jest zdefiniowane, ale sprawia, że ​​nie ma szans na Ciebie, ponieważ nie jesteś uruchamianiu go.

Właściwie to byłoby mieć możliwość < 0> specjalizacja zawierać błędy składniowe i program by jeszcze skompilować bez błędów! Wynika to z faktu, że formalnie szablony są kompilowane tylko wtedy, gdy są używane. (I nie spodziewałbym kandydatem mieć przytomność umysłu w warunkach wywiadu wskazują, że obecnie).

+0

"specjalizacja <0> może zawierać błędy składni, a program nadal będzie kompilowany bez błędu!" - prawda, ale tylko z lekkimi kompilatorami. Inne kompilatory tego nie będą miały. – ach

+0

Nie, to część standardu. – Bathsheba

+0

Twierdzę, że nawet jeśli jest to część standardu, specjalizacja <0> zawierająca błędy składniowe tylko _might_ compile; nie można tego zagwarantować. Jeśli zawiera dodatkowy niedopasowany błąd składni '}', kompilator może mieć problemy z ustaleniem, gdzie definicja funkcji ma się zakończyć, powodując niepoprawne parsowanie linii. – Variadicism

Powiązane problemy