2016-12-14 26 views
10

下面的代碼編譯失敗live on Ideone初始化constexpr與常量:和不同的治療對於int雙

#include <iostream> 
using namespace std; 

int main() { 
    const double kPi = 3.14; 
    constexpr double kPi2 = 2.0*kPi; 
    cout << kPi2; 
} 

的錯誤信息是:

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; 

代入const聲明kPiconstexpr,it compiles successfully

在另一方面,當int是用來代替double,好像constplays wellconstexpr

#include <iostream> 
using namespace std; 

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

爲什麼intdouble得到不同的治療方法用於初始化與const一個constexpr
這是Ideone編譯器中的錯誤嗎?這是C++標準所要求的嗎?這是爲什麼?
上述代碼是否爲UB?

P.S.我嘗試使用Visual Studio 2015 C++編譯器,它編譯第一個代碼片段(初始化constexprconst)就好了。

+2

[問題1826:在常量表達式const的浮點](http://stackoverflow.com/a/30742473/1708801)介紹了爲什麼浮點被區別對待的一些歷史。另外[有趣的不贊成gcc exntension](http://stackoverflow.com/q/32813953/1708801)。 –

+0

@ShafikYaghmour謝謝。我提高了這個帖子。 –

+0

看起來像@ ShafikYaghmour的評論應該被提升爲答案,然後被接受。 – TriskalJM

回答

-3

規則:「constexpr必須評估在編譯時間」。我們來看下面的代碼(通用示例);

const double k1 = size_of_array(); 

k1爲常數,其初始值是不知道編譯時但其初始化是已知的,直到運行時所以k1爲不常量表達式。結果const變量不是constexpr。

但是編譯器看到這些代碼:

const int k1 = 10; 
    constexpr int k2 = 2*k1; 

一個例外發生。 只要需要const整數,可以使用constexpr整數值,例如模板參數和數組聲明[1]

您可以從下面的鏈接獲得額外的信息:

  1. Constexpr - Generalized Constant Expressions in C++11
  2. const vs constexpr on variables | stackoverflow
  3. Difference between constexpr and const | stackoverflow
+0

這並不回答這個問題,它是關於'const double k1 = 3.14;'而不是'const double k1 = size_of_array();' –

+0

當然** double k1 = size_of_array(); **不包括有問題但我給了關於const值的例子**編譯時間**和**運行時初始化**。而這個關於每個const變量的例子都不是constexpr(常量表達式)。在這個給定的信息之後,這個問題的答案是:constexpr整型值可以用在需要const整數的地方,比如在模板參數和數組聲明中。[MSDN](https://msdn.microsoft.com/en-us /library/dn956974.aspx) – straceX

+0

這個問題是關於編譯時初始化的值,與運行時初始化的例子沒有關係。你的回答看起來好像OP代碼的問題是運行時初始化。 –

0

沙菲克Yaghmour已經提供了link explaining the background

由於我必須保持其具有不同的標準,我使用下面的宏以編譯的代碼:

#if __cplusplus <= 199711L // lower than C++11 
    #define MY_CONST const 
#else // C++11 and above 
    #define MY_CONST constexpr 
#endif