jac*_*k X 6 c++ templates language-lawyer
考虑这个例子:
template<int const& rf>
struct A{
void fun(){
constexpr int v = rf; //#1
}
};
int const object = 0;
int main(){
A<object> a;
a.fun();
}
Run Code Online (Sandbox Code Playgroud)
GCC和锵都同意该rf可被用作一常量表达式。
但是,在这种情况下,rf是一个 id 表达式。因此,只有满足以下规则的 id 表达式才能用于常量表达式。相关规则是:
[expr.const#5.12]
引用变量或引用类型数据成员的 id 表达式,除非该引用具有前面的初始化并且
- 它可用于常量表达式或
- 它的生命周期开始于 E 的评估;
对于 id 表达式rfat #1,它的生命周期不在初始化的评估内开始。所以,子弹2在这里不满足。根据声明constexpr int v = rf;,其中 id-expressionrf没有前面的初始化。对于子弹 1,相关规则说:
甲恒定初始化潜在常数变量V是在点P处常量表达式可用如果五世的初始化声明d是可到达的选自P及
- V 是 constexpr
- V 未初始化为 TU 本地值,或
- P 与 D 在同一个翻译单元中。
rf不是常量初始化的,因为它既没有初始化器,也没有它的默认初始化导致执行一些初始化。因此,ID-表达式rf中使用#1会违反[expr.const#5.12。因此,它不能用于#1. 实际上,所有编译器都同意rf可以在常量表达式中使用(它也符合直观)。但是,标准中的规则在这里发生冲突。这个怎么解释?它是否缺少可用于常量表达式的非类型模板参数的措辞?