使用const初始化constexpr:int和double的不同处理

Mr.*_*C64 14 c++ const constexpr c++11

以下代码无法在Ideone上实时编译:

#include <iostream>
using namespace std;

int main() {
    const double kPi = 3.14;
    constexpr double kPi2 = 2.0*kPi;
    cout << kPi2;
}
Run Code Online (Sandbox Code Playgroud)

错误消息是:

prog.cpp: In function 'int main()':
prog.cpp:6:30: error: the value of 'kPi' is not usable in a constant expression
  constexpr double kPi2 = 2.0*kPi;
                              ^
prog.cpp:5:15: note: 'kPi' was not declared 'constexpr'
  const double kPi = 3.14;
Run Code Online (Sandbox Code Playgroud)

const声明替换为kPiwith constexpr,它会成功编译.

在另一方面,如果int是用来代替double,好像const 还有戏剧constexpr:

#include <iostream>
using namespace std;

int main() {
    const int k1 = 10;
    constexpr int k2 = 2*k1;
    cout << k2 << '\n';
    return 0;
}
Run Code Online (Sandbox Code Playgroud)

为什么intdouble初始化一个得到不同的治疗方法constexprconst
这是Ideone编译器中的错误吗?这是C++标准所要求的吗?这是为什么?
上面的代码是UB吗?

PS我试图与Visual Studio 2015年C++编译器,并将其编译的第一个代码段(初始化constexprconst)就好了.

str*_*ceX -3

规则:“constexpr 必须在编译时求值”。

让我们看下面的代码(通用示例);

    const double k1 = size_of_array(); 
Run Code Online (Sandbox Code Playgroud)

k1 是常量,其初始值设定项的值在编译时未知,但其初始值设定项直到运行时才已知,因此 k1 不是常量表达式。因此 const 变量不是 constexpr。

但编译器看到这些代码:

    const int k1 = 10;  
    constexpr int k2 = 2*k1;
Run Code Online (Sandbox Code Playgroud)

出现一例外情况。constexpr 整数值可以用在需要 const 整数的地方,例如在模板参数和数组声明中 [1]

您可以从以下链接获取额外信息:

  1. Constexpr - C++11 中的广义常量表达式
  2. 变量上的 const 与 constexpr | 堆栈溢出
  3. constexpr和之间的区别const| 堆栈溢出