局部变量作为非typename参数

时间:2013-06-27 23:05:05

标签: c++ templates c++11

为什么将局部变量用作非类型参数是非法的?

例如,在下一个代码中local_var不能成为X的参数。

template<int& x> struct X {};

void f(int local_var)
{
    X<local_var> x;
}

2 个答案:

答案 0 :(得分:6)

因为模板参数必须在编译时计算,并且编译器在运行时才知道局部变量的地址(为了绑定对象的引用,编译器需要知道该地址的地址对象)。

请注意,C ++ 11标准确切地说明了第14.3.2 / 1段中可以提供的非类型模板参数:

  

非类型非模板模板参数 template-argument 应为以下之一:

     

- 对于整数或枚举类型的非类型模板参数,转换后的常量表达式   (5.19) template-parameter 的类型;或

     

- 非类型模板参数的名称;或

     

- 一个常量表达式(5.19),用于指定具有静态存储持续时间和的对象的地址   外部或内部链接或具有外部或内部链接的功能,包括功能模板   和函数 template-ids 但不包括非静态类成员,表示(忽略括号)为   &安培; id-expression ,除了&amp;如果名称引用函数或数组,则可以省略   如果相应的模板参数是引用,则省略;或

     

- 一个求值为空指针值的常量表达式(4.10);或

     

- 一个求值为空成员指针值的常量表达式(4.11);或

     

- 指向成员的指针,如5.3.1所述;或

     

- 类型std::nullptr_t的地址常量表达式。

如您所见,本地变量不在此列表中。

答案 1 :(得分:0)

模板的“值”需要在编译时出现。

template<int x> struct X {};

即使您没有绑定引用或在此处传递指针,编译器也必须在编译时知道传递元素的值。

此处有意将int &x替换为int x。关于int&amp;的东西得到了正确回答。我只是想指出它适用于所有非类型模板参数。

  • 引用的“值”是一个引用(实现依赖于其中大部分指针)
    • 必须在编译时知道对象的地址
  • 指针template<int*>的“值”是一个地址......
    • ......当然,这也必须在这里知道。
  • 值类型的“值”是值本身,在编译时也必须知道

X<local_var> x; // will not work, local_var does not exist at compile time
X<1> x; // works since 1 is known

我只想(除了Andy的回答)阻止任何建议使用值类型而不是引用的结论。