`constexpr`和`const`之间的区别?
基本含義和語法
這兩個關鍵字都可以在對象聲明和函數中使用。應用于對象的基本區別是:
- const聲明一個對象為常量。這意味著一個保證,一旦初始化,該對象的值不會改變,編譯器可以利用這個事實進行優化。它還有助于防止程序員編寫修改初始化后不打算修改的對象的代碼。
- constexpr聲明一個對象適合在Standard調用常量表達式中使用。但請注意,這constexpr不是唯一的方法。
應用于功能的基本區別是:
- const只能用于非靜態成員函數,而不能用于一般函數。它保證了成員函數不會修改任何非靜態數據成員。
- constexpr可以與成員和非成員函數以及構造函數一起使用。它聲明了適用于常量表達式的函數。如果函數符合某些標準(7.1.5 / 3,4),編譯器將只接受它,最重要的是(?):
- 函數體必須是非虛擬的,非常簡單:除typedef和靜態斷言之外,只return允許一個語句。在構造函數的情況下,只允許初始化列表typedefs和靜態聲明。(= default和= delete也被允許使用,但。)
- 參數和返回類型必須是文字類型(即一般來說,非常簡單的類型,通常是標量或集合)
?
常量表達式
如上所述,constexpr聲明兩個對象以及適合在常量表達式中使用的函數。一個恒定的表達不僅僅是不變的:
- 它可用于需要編譯時評估的地方,例如模板參數和數組大小說明符:?template<int N> class fixed_size_list { /*...*/ };??fixed_size_list<X> mylist; // X must be an integer constant expression??int numbers[X]; // X must be an integer constant expression
- 但請注意:
- 聲明一些東西constexpr并不一定保證在編譯時會被評估。它可以用于此類,但也可以在運行時評估的其他地方使用。
- 一個對象可能適合在常量表達式中使用,而不需要聲明constexpr。例:?int main() { const int N = 3; int numbers[N] = {1, 2, 3}; // N is constant expression return 0; }
這是可能的,因為N在聲明時使用常量來保持常量和初始化,即使沒有聲明,它也滿足常量表達式的條件constexpr。
那么我什么時候需要使用constexpr?
- 像上面這樣的對象N可以作為常量表達式使用而不需要聲明constexpr。所有對象都是如此:
- const
- 積分或枚舉類型和
- 在聲明時用一個本身就是常量表達式的表達式進行初始化
[這是由于§5.19/ 2:一個常量表達式不能包括一個子表達式,涉及“左值,右值修改,除非[...]整數或枚舉類型的glvalue”感謝理查史密斯糾正我早些時候聲稱這對所有字面類型都是正確的。]
- 要使函數適合在常量表達式中使用,必須明確聲明constexpr; 僅僅滿足常量表達函數的標準是不夠的。例:?template<int N> class list { };??constexpr int sqr1(int arg) { return arg * arg; }??int sqr2(int arg) { return arg * arg; }??int main() { const int X = 2; list<sqr1(X)> mylist1; // OK: sqr1 is constexpr list<sqr2(X)> mylist2; // wrong: sqr2 is not constexpr return 0; }
我什么時候可以同時使用const和constexpr?一起使用?
A.在對象聲明中。當兩個關鍵字都指向同一個被聲明的對象時,這是不必要的。constexpr意味著const。
constexpr const int N = 5;是相同的
constexpr int N = 5;但是,請注意,可能會出現以下情況:關鍵字分別指向聲明的不同部分:
static constexpr int N = 3;int main() {constexpr const int *NP = &N;return 0; }在這里,NP被聲明為一個地址常量表達式,即一個本身就是一個常量表達式的指針。(當通過將地址運算符靜態/全局常量表達式生成的地址。這是可能的。)在這里,無論是constexpr和const是必需的:constexpr總是指表達被宣布(在這里NP),而const指的是int(它聲明了一個指針-給const)。刪除const會導致表達式不合法(因為(a)非const對象的指針不能是常量表達式,(b)&N實際上是指向常量的指針)。
B.在成員函數聲明中。在C ++ 11中,也constexpr暗示const了成員函數。但是,這在C ++ 14中可能會改變。根據目前的草案,由于建議修改§7.1.5/ 8 ,constexpr將const?僅針對對象,而不針對成員職能。因此,在C ++ 11下聲明一個成員函數為
constexpr void f();將不得不被宣布為
constexpr void f() const;在C ++ 14下仍然可以用作const函數。最好將你的constexpr成員函數標記為const現在,以免稍后改變很多代碼。
總結
以上是生活随笔為你收集整理的`constexpr`和`const`之间的区别?的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: C++ 11 新特性: constexp
- 下一篇: C++ 调试帮助简介