【发布时间】:2017-12-20 15:01:12
【问题描述】:
这段代码中的表达式b应该是一个核心常量表达式
int main()
{
constexpr int a = 10;
const int &b = a;
constexpr int c = b; // here
return 0;
}
因为标准说(n4700 中的 8.20,第 2 段 [expr.const])
表达式
e是一个核心常量表达式,除非对e将评估以下表达式之一:
...
左值到右值的转换 (7.1),除非它应用于
...
非易失性左值,指的是用 constexpr 定义的非易失性对象,或指代此类对象的非可变子对象, 或
首先,上面代码中的表达式b 是一个左值(也是一个左值),因为它是一个引用,因此是一个变量(8.1.4.1,第 1 段)
[expr.prim.id.unqual]):
如果实体是函数,则表达式是左值, 变量,或数据成员和纯右值;如果标识符指定位域 (11.5),则它是位域。
其次,变量b表示的对象是a,用constexpr声明。但是,gcc 抱怨
./hello.cpp: In function ‘int main()’:
./hello.cpp:6:20: error: the value of ‘b’ is not usable in a constant expression
constexpr int c = b;
^
./hello.cpp:5:13: note: ‘b’ was not declared ‘constexpr’
const int &b = a;
据我所知,引用不是对象,因此上面的项目符号显然表明a 应使用constexpr 声明。我错过了什么吗?我不同意 gcc 的原因是 gcc 将b 视为一个对象,因此需要用constexpr 声明它。但是,b 不是对象!
【问题讨论】:
-
Clang 同意 GCC。但我想我同意你的观点,这是标准或编译器的缺陷。另外值得注意的是,MSVC 接受代码。
标签: c++ language-lawyer c++17