6

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

例如,在下一个代码local_var中不能作为X.

template<int& x> struct X {};

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

2 回答 2

6

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

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

非类型、非模板模板参数模板参数应为以下之一:

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

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

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

— 一个常量表达式,计算结果为空指针值 (4.10);或者

— 一个常量表达式,其值为空成员指针值 (4.11);或者

— 一个指向成员的指针,如 5.3.1 所述;或者

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

如您所见,局部变量不在此列表中。

于 2013-06-27T23:06:10.070 回答
0

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

template<int x> struct X {};

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

替换int &xint x这里是故意的。关于 int& 的东西得到了正确的回答。我只是想指出它适用于所有非类型化模板参数。

  • 引用的“值”是一个引用(在大多数情况下,实现依赖实际上是一个指针)
    • 编译时必须知道对象的地址
  • 指针的“值”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

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

于 2013-06-27T23:09:55.747 回答