2011-11-22 10 views
5

Mam następujący kod:Błąd kompilacji szablonu - standardowy czy nie?

template<int k> 
void foo() 
{ 
} 
int main(int argc, char* argv[]) 
{ 
    int k = 1000; 
    foo<k>(); 
    return 0; 
} 

które nie kompiluje, ale jeśli Oświadczam k jak const, robi:

template<int k> 
void foo() 
{ 
} 
int main(int argc, char* argv[]) 
{ 
    const int k = 1000; 
    foo<k>(); 
    return 0; 
} 

Teraz widzę logikę dlaczego w pierwszym przypadku nie kompiluje się, a w drugim robi, ale czy jest to określone przez standard?

Błąd Dostaję jest:

Error 1 error C2971: 'foo' : template parameter 'k' : 'k' : a local variable cannot be used as a non-type argument 

co nie jest do końca jasne, ponieważ k jest zmienna lokalna również w przypadku jest to const ... prawda?

Odpowiedz

2

§14.3.2.1 mówi [skrócona]:

A template-argument for a non-type, non-template template-parameter shall be one of:
— an integral constant-expression of integral or enumeration type;

And §5.19 0,1 mówi [skrócona, podkr]:

An integral constant-expression can involve only literals, enumerators, const variables or static data members of integral or enumeration types initialized with constant expressions...

Twoja druga definicja k spełnia tego, więc może być stosowany jako WKP dla argumentu szablonu.

Błąd jest nieco mylący, ponieważ "zmienna lokalna nie może być używana jako argument nie typu" jest prawdziwa ogólnie, ale z pewnymi ograniczeniami jest całkowicie w porządku.

4

Per standardu, 14.3.2, to musi być stałym wyrażeniem:

A template-argument for a non-type, non-template template-parameter shall be one of:
an integral constant-expression of integral or enumeration type; or
— the name of a non-type template-parameter; or
— the address of an object or function with external linkage, including function templates and function template-ids but excluding non-static class members, expressed as & id-expression where the & is optional if the name refers to a function or array, or if the corresponding template-parameter is a reference; or
— a pointer to member expressed as described in 5.3.1 .

GCC 4.6.2 daje nieco bardziej zrozumiały błąd:

error: ‘k’ cannot appear in a constant-expression

+0

Nie sprecyzowałeś, dlaczego "k" działa w jednym, ale nie w drugim, co stanowiło mięso tego pytania. – GManNickG

+0

Zobacz sekcję I pogrubioną. Standard mówi, że wyrażenie musi być stałe. –

+0

Ale powtarzam: nie rozumiesz, dlaczego 'k' jest użyteczny, czy nie. – GManNickG

2

wartości Nr Const może być oceniane w czasie kompilacji, gdy kompilator próbuje rozszerzyć szablony do ostatecznej formy. Tak Wartości wykonanie wymiarze godzin nie mogą być argumenty na szablonach, ale zawsze można ustawić odwołanie do zmiennej jako argumentu szablonu

template<int& k> 
void foo() 
{ 
} 
int main(int argc, char* argv[]) 
{ 
    int k = 1000; 
    foo<k>(); 
    return 0; 
} 
Powiązane problemy