2011-11-22 9 views
5

Ho il seguente codice:Errore di compilazione del modello - standard o no?

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

che non compilare, ma se io dichiaro k come const, lo fa:

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

Ora, vedo la logica dietro perché nel primo caso non si compila e nel secondo lo fa, ma è specificato dallo standard?

L'errore che sto ottenendo è:

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

che non è esattamente chiaro, dal momento che k è una variabile locale anche nel caso è const ... giusto?

risposta

2

§14.3.2.1 dice [abbreviata]:

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

E §5.19 .1 dice [in forma abbreviata, corsivo mio]:

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

la seconda definizione di k soddisfa questo, quindi è permesso di essere utilizzato come un ICE per l'argomento modello.

L'errore è leggermente fuorviante in quanto "una variabile locale non può essere utilizzata come argomento non di tipo" è vera in generale, ma con alcune restrizioni è perfettamente soddisfacente.

4

Per lo standard, 14.3.2, ciò deve essere un'espressione costante:

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 dà un errore leggermente più comprensibile:

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

+0

Non hai specificato perché 'k' funziona in uno ma non nell'altro, che era la carne della domanda. – GManNickG

+0

Vedere la sezione I in grassetto. Lo standard dice che l'espressione deve essere costante. –

+0

Ma mi ripeto: non si affronta perché 'k' è utilizzabile o no. – GManNickG

2

valori No. Const può essere valutato al momento della compilazione quando il compilatore tenta di espandere i modelli alla forma finale. Quindi i valori di esecuzione-tempo non può essere argomenti per i modelli, ma sempre è possibile impostare riferimento alla variabile come argomento di un template

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