const变量的值在常量表达式中可用或不可用,具体取决于变量类型

Geo*_*org 13 c++ const constexpr c++11

以下代码没问题:

constexpr double square_cstxpr(double x) { return x * x; }

int main() {
    const int test = 5;
    constexpr double result = square_cstxpr((double)test);
}
Run Code Online (Sandbox Code Playgroud)

但是,如果类型test从更改const intconst double,则g ++会出现以下错误:the value of 'test' is not usable in a constant expression.

请在此处查看g ++的代码和输出:http://coliru.stacked-crooked.com/a/2fe9b176c2b23798

有人可以解释一下这种行为吗?

Edg*_*jān 7

常量表达式(核心常量表达式):

10)任何其他左值到右值的隐式转换,除非左值...

a)具有整数或枚举类型,并且指的是一个完整的非易失性const对象,它用一个常量表达式初始化

这意味着,在这里:

const int test1 = 5;
constexpr double result1 = square_cstxpr((double)test1);
Run Code Online (Sandbox Code Playgroud)

test1是一个常量表达式,square_cstxpr可以test1在编译时作为参数调用,其结果可以分配给constexpr变量 result.

另一方面,这里:

const double test2 = 5;
constexpr double result2 = square_cstxpr((double)test2);
Run Code Online (Sandbox Code Playgroud)

test2不是常量表达式,因为它不是整数或枚举类型.因此,square_cstxpr不能在编译时以test2参数形式调用.


Col*_*mbo 6

constexprconst变量必须是整数或枚举类型的用于他们在常量表达式可用.见[expr.const]/2:

除非适用,否则左值转换为左值

(2.7.1)一个非整数或枚举类型的非易失性glvalue, 它引用一个完整的非易失性const对象,具有前面的初始化,用常量表达式初始化,或者[...]

这种限制的原因必须主要是历史性的.在涉及常量表达式时,浮点数已经小心处理; 想想非类型模板参数.这是由于它们强烈依赖于平台的行为,这使得编译时计算的数学性能低于应有的数学时间.