【发布时间】:2015-04-24 03:03:26
【问题描述】:
下面的示例尝试使用引用类型的变量作为非类型模板形参(其本身为引用类型)的实参。 Clang、GCC 和 VC++ 都拒绝它。但为什么?我似乎在标准中找不到任何使其非法的内容。
int obj = 42;
int& ref = obj;
template <int& param> class X {};
int main()
{
X<obj> x1; // OK
X<ref> x2; // error
}
CLang 说:
source_file.cpp:9:7: 错误:引用类型“int &”的非类型模板参数不是对象
其他人也以类似的方式抱怨。
来自标准(所有引用来自 C++11;C++14 的相关部分似乎没有重大变化):
14.3.2/1 用于非类型、非模板的 template-argument template-parameter 应为以下之一:
...
- 一个常量表达式 (5.19),它指定具有静态存储持续时间和外部或内部链接的对象的地址...表示(忽略括号)为
&id-expression,除了&... 如果对应的模板参数是参考,则应省略...
现在什么是常量表达式:
5.19/2 条件表达式是一个核心常量表达式,除非它涉及以下之一作为潜在评估的子表达式(3.2 )...
...
- 一个id-expression,它引用引用类型的变量或数据成员,除非该引用具有前面的初始化,用常量表达式初始化
...
据我所知,X<ref> 中的ref 是一个id-expression,它引用了一个引用类型的变量。这个变量有一个前面的初始化,用表达式obj 初始化。我相信obj 是一个常量表达式,无论如何如果不是,那么X<obj> 也不应该编译。
- 那么我错过了什么?
- 标准中的哪个条款使
X<ref>无效,而X<obj>有效?
【问题讨论】:
标签: c++ c++11 language-lawyer