3 回答

TA貢獻1818條經驗 獲得超11個贊
我相信存在差異。讓我們重命名它們,以便我們可以更容易地討論它們:
const double PI1 = 3.141592653589793;
constexpr double PI2 = 3.141592653589793;
這兩個PI1和PI2是不變的,這意味著你不能修改它們。但是只有 PI2編譯時常量。它應在編譯時初始化。 PI1可以在編譯時或運行時初始化。此外,只能 PI2在需要編譯時常量的上下文中使用。例如:
constexpr double PI3 = PI1; // error
但:
constexpr double PI3 = PI2; // ok
和:
static_assert(PI1 == 3.141592653589793, ""); // error
但:
static_assert(PI2 == 3.141592653589793, ""); // ok
至于你應該使用哪個?使用符合您需求的任何一種。您是否希望確保您具有可在需要編譯時常量的上下文中使用的編譯時常量?您是否希望能夠在運行時進行計算來初始化它?等等。

TA貢獻1909條經驗 獲得超7個贊
這里沒有區別,但是當你有一個具有構造函數的類型時,這很重要。
struct S {
constexpr S(int);
};
const S s0(0);
constexpr S s1(1);
s0是一個常量,但它不承諾在編譯時初始化。s1是標記的constexpr,所以它是一個常量,因為它S的構造函數也被標記constexpr,它將在編譯時初始化。
大多數情況下,這很重要,因為在運行時初始化會非常耗時,并且您希望將該工作推送到編譯器上,這也很耗時,但不會減慢編譯程序的執行時間

TA貢獻1895條經驗 獲得超7個贊
constexpr表示編譯期間常量且已知的值。
const表示一個僅為常數的值; 在編譯期間不必知道。
int sz;
constexpr auto arraySize1 = sz; // error! sz's value unknown at compilation
std::array<int, sz> data1; // error! same problem
constexpr auto arraySize2 = 10; // fine, 10 is a compile-time constant
std::array<int, arraySize2> data2; // fine, arraySize2 is constexpr
請注意,const不提供與constexpr相同的保證,因為const對象無需使用編譯期間已知的值進行初始化。
int sz;
const auto arraySize = sz; // fine, arraySize is const copy of sz
std::array<int, arraySize> data; // error! arraySize's value unknown at compilation
所有constexpr對象都是const,但并非所有const對象都是constexpr。
如果您希望編譯器保證變量的值可以在需要編譯時常量的上下文中使用,那么要實現的工具是constexpr,而不是const。
- 3 回答
- 0 關注
- 831 瀏覽
添加回答
舉報