2011-11-22 134 views
5

我有以下代码:模板编译错误 - 标准与否?

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

根本不能编译,但是如果我宣布kconst,它的作用:

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

现在,我看到背后的逻辑,为什么在第一它不会编译,在第二种情况下,它是由标准规定的?

我得到的错误是:

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

这是不完全清楚,因为k是一个局部变量也是它的const的情况下,对吧?

回答

2

§14.3.2.1说[有删节]:

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

而且§5.19 0.1说[有删节,重点煤矿]:

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

你的k满足第二个定义,所以它允许用作模板参数的ICE。

这个错误有点误导,“一个局部变量不能用作非类型参数”是真的一般,但有一定的限制,它是完全没问题的。

4

每标准,14.3.2,这必须是常量表达式:

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给出了稍微更明显易懂错误:

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

+0

你没有具体说明为什么'k'能在一个而不是另一个中工作,这是问题的关键。 – GManNickG

+0

请参阅粗体部分。该标准表示该表达式必须是恒定的。 –

+0

但我再重复一遍自己:你没有解释为什么'k'可用或不可用。 – GManNickG

2

号CONST值可以是当编译器试图将模板扩展到最终形式时,评估编译时间。所以,执行时间值不能作为模板参数,但总是可以设置参考变量作为模板参数

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