亚洲欧美第一页_禁久久精品乱码_粉嫩av一区二区三区免费野_久草精品视频

蟲蟲首頁| 資源下載| 資源專輯| 精品軟件
登錄| 注冊

您現在的位置是:首頁 > 技術閱讀 >  constexpr

constexpr

時間:2024-02-15

前面介紹了模板這種編譯期動作,關于編譯期動作,有必要介紹下constexpr。


在這之前有必要簡單提一下constexpr與const的關系,兩者字面上都表達常量的意思。


主要的區別是:const修飾的變量可以在運行時才初始化,而constexpr則一定會在編譯期初始化。


constexpr才是名符其實的常量,所有的constexpr都是const。


而const表示的是read only的語義,保證修飾的變量運行時不可以更改,如果直接改動它,編譯器在編譯時會報錯。const修飾的變量可以在運行時才初始化,而constexpr則一定會在編譯期初始化。


有人可能會用指針等騷操作來修改const修飾的變量值,這種情況下,CPP標準規定產生的是未定義行為,具體可能不同編譯器的具體行為會不相同。所以騷操作魔改const后,無論產生什么行為,都沒必要奇怪,也沒必要深究。



下面具體介紹下constexpr


如上所述,constexpr修飾的才是真正的常量,它會在編譯期間計算出來,整個運行過程中都不可被改變。


constexpr還可用于修飾函數,這個函數的返回值會盡可能在編譯期間被計算出來,然后作為一個常量,但是如果編譯期間不能被計算出,此函數就是被當作一個普通函數處理。


如何使用constexpr?


這里我直接貼出cppreference中的示例代碼:

#include <iostream>#include <stdexcept>// C++11 constexpr functions use recursion rather than iteration// (C++14 constexpr functions may use local variables and loops)constexpr int factorial(int n) { return n <= 1 ? 1 : (n factorial(n - 1)); }
// literal classclass conststr { const char p; std::size_t sz;public: template <std::size_t N> constexpr conststr(const char (&a)[N]) : p(a), sz(N - 1) {} // constexpr functions signal errors by throwing exceptions // in C++11, they must do so from the conditional operator ?: constexpr char operator[](std::size_t n) const { return n < sz ? p[n] : throw std::out_of_range(""); }
constexpr std::size_t size() const { return sz; }};
// C++11 constexpr functions had to put everything in a single return statement// (C++14 doesn't have that requirement)constexpr std::size_t countlower(conststr s, std::size_t n = 0, std::size_t c = 0) { return n == s.size() ? c : 'a' <= s[n] && s[n] <= 'z' ? countlower(s, n + 1, c + 1) : countlower(s, n + 1, c);}
// output function that requires a compile-time constant, for testingtemplate <int n>struct constN { constN() { std::cout << n << '\n'; }};
int main() { std::cout << "4! = "; constN<factorial(4)> out1; // computed at compile time volatile int k = 8; // disallow optimization using volatile std::cout << k << "! = " << factorial(k) << '\n'; // computed at run time
std::cout << "the number of lowercase letters in \"Hello, world!\" is "; constN<countlower("Hello, world!")> out2; // implicitly converted to conststr}


可以大體觀察到constexpr的語法如下:

constexpr literal-type identifier = constant-expression ;constexpr literal-type identifier { constant-expression } ;constexpr literal-type identifier ( params ) ;constexpr ctor ( params ) ;


通過示例代碼及相關注釋,就可以看到,能在編譯期做constexpr就會優先在編譯期計算,編譯期不行就在運行時計算。


也可以看到,在C++14之前constexpr修飾函數時不能有if-else for循環等語句,而在C++14后,這個問題有了改善。


那什么情況下應該使用constexpr修飾函數?


不在乎編譯時間的話,盡可能用constexpr修飾所有的函數,大家有時間可以看看cpp的源碼,多數成員函數都是使用的constexpr修飾。


思考題

constexpr有一個條件是需要滿足literal type,那literal type究竟是什么類型?


推薦閱讀:

https://docs.microsoft.com/en-us/cpp/cpp/constexpr-cpp?view=msvc-170


參考資料

https://en.cppreference.com/w/cpp/language/constexpr

主站蜘蛛池模板: 乐昌市| 读书| 德钦县| 乳源| 万安县| 高淳县| 彭水| 朝阳市| 辉县市| 山阴县| 旺苍县| 固阳县| 奉贤区| 舞钢市| 肥城市| 随州市| 伊金霍洛旗| 驻马店市| 息烽县| 时尚| 资溪县| 洛南县| 阳东县| 西乌珠穆沁旗| 驻马店市| 祁连县| 六盘水市| 庄河市| 东乡族自治县| 鄂州市| 沅江市| 利川市| 休宁县| 曲水县| 龙口市| 祁东县| 龙口市| 阳山县| 锡林浩特市| 日土县| 鲁甸县|