C++ constexpr的使用小結(jié)
constexpr是C++的修飾詞,用于指定“編譯期可以求數(shù)值的常量表達式”,可用于修飾變量,函數(shù),類/結(jié)構(gòu)體,構(gòu)造函數(shù)/析構(gòu)函數(shù),模板五種情況,作用就是支持編譯期常量處理。constexpr的實際應(yīng)用中最常用的是修飾變量和函數(shù)。
constexpr用于修飾變量,可以構(gòu)建真常量,即編譯器常量。constexpr用于修飾函數(shù),可以用于編譯期求值;constexpr用于修飾類/結(jié)構(gòu)體??梢杂脕碓诰幾g期構(gòu)造對象;constexpr用于修飾構(gòu)造函數(shù)/析構(gòu)函數(shù),可以在編譯器就對類對象進行初始化/銷毀;constexpr用于修飾模板,在編譯期間完成模板實例化進行求數(shù)值。
增加編譯期間求解的效果是提升性能、增強類型安全。
實例1——constexpr修飾變量:
#include <iostream> constexpr int MAXsize = 100; // 由constexptr修飾的int型真常量, //在編譯期就可以通過直接賦值確定取值為100. constexpr int OVERsize = MAXsize + 50; //在編譯期可以通過計算得到確定取值為150. //由constexpr修飾的MAXsize和OVERsize兩個真常量,分別取值100和150. //編譯正常。符合處理直覺。
提問: constexpr 可以修飾變量,此時該變量是編譯期常量(值必須在編譯期確定,且生命周期內(nèi)不可修改,比 const 更嚴格)如果這個變量的取值在編譯期間沒有確定會報錯嗎?還是任意給這個變量取定一個隨機值?取定隨機值會導(dǎo)致這個變量實際沒有可用效果? 以及這里講的生命周期不可修改是什么意思?一個constexpr修飾的真常量的生命周期不就是整個程序運行的期間都有效嗎?編譯期常量即真常量是不占用C++堆內(nèi)存和棧內(nèi)存的吧!
解答:
// constexpr 修飾變量,這個變量的數(shù)值必須在編譯期確定,生命周期內(nèi)不可修改。
// 如果編譯期間這個變量的數(shù)值沒有確定指定,會直接編譯報錯,無隨機值。
// constexpr 修飾得到的真常量在生命周期內(nèi)都只具有只讀屬性,不可修改。
// constexpr 修飾得到的真常量的生命周期取決于變量定義所在的作用域決定。
// 即constexpr只負責(zé)跟編譯器通力合作在編譯期間確定數(shù)值。
// 至于這個真常量在何時失效取決于這個變量的自身的作用域,
// 即定義在函數(shù)內(nèi)部的變量,即便加上constexpr修飾,
// 這個真常量的生命周期依然只在函數(shù)內(nèi)的局部作用域效果下。constexpr修飾的真常量被存儲在靜態(tài)只讀數(shù)據(jù)區(qū)。
總結(jié)1:
constexpr修飾變量,得到真常量,存儲在靜態(tài)存儲區(qū),不占用運行內(nèi)存;(因此增強性能)constexpr修飾得到的真常量,如果沒有在編譯期指定,直接報錯。constexpr修飾得到的真常量,生命周期內(nèi)權(quán)限為只讀,不可修改。constexpr修飾得到的真常量,生命周期長度取決于變量本身的生命周期。
實例2——constexpr修飾函數(shù):
表示這個函數(shù),如果入?yún)⑹蔷幾g期常量,在編譯期完成計算得到處理結(jié)果。如果入?yún)⒉皇蔷幾g期間常量,那就退化成普通函數(shù)。兩種情況都不會報錯。UDL和普通函數(shù)都支持這種退化兼容。
//constexpr修飾UDL(自定義字面值運算符)
constexpr long long operator "" _KM2m(long long kilometer) {
return kilometer*1000;
}
//constexpr修飾普通函數(shù)
constexpr int add(int a, int b){
return a + b;
}
實例3——constexpr修飾類/結(jié)構(gòu)體:
作用是在編譯期構(gòu)造類對象,即編譯期常量對象。 要求:
- 類的構(gòu)造函數(shù)必須是
constexpr構(gòu)造函數(shù); - 編譯期內(nèi)需調(diào)用的成員函數(shù)也必須有
constexpr修飾; - 類的成員變量中,對于被
constexpr使用/依賴的靜態(tài)成員變量,必須在類內(nèi)constexpr修飾。而且最好直接用static constexpr
//constexpr修飾結(jié)構(gòu)體(在C++中將結(jié)構(gòu)體視為類的一種)
struct Point{
//constexpr 修飾構(gòu)造函數(shù)
constexpr Point(int x_, int y_) : x(x_), y(y_) {}
// C++中約定俗成用 變量名右加下劃線 表示類成員變量的命名。
// x(x_), y(y_) 是 C++ 中的「成員初始化列表(Member Initialization List)
// 效果是將x_,y_的值對應(yīng)賦值給x,y
// `x(x_)` 和 `x=x_` 在初始化列表中等價
//constexpr 修飾構(gòu)造函數(shù)
constexpr int get_x() const {
return}
}
int x;
int y;
}
int main () {
//編譯器構(gòu)造Ponit對象
constexpr Point p0(10,20);
//編譯期調(diào)用成員函數(shù),獲取數(shù)值
constexpr int x_val = p0.get_x();
return 0;
}
- 非靜態(tài)成員變量是指屬于單個對象的變量,每個對象獨一份,生命周期隨對象變化;
- 靜態(tài)成員變量屬于類本身的,所有對象共享一份,生命周期貫穿程序。
- 靜態(tài)const成員變量:類內(nèi)直接初始化,因為貫穿程序的生命周期,且在運行期間數(shù)值不可修改,是綁定在整個類上的變量。
static const變量類型 變量名 = 初始化數(shù)值;static constexpr變量類型 變量名 = 初始化數(shù)值; 效果更好。
- -這里的static其實是指類共享。靜態(tài)變量本質(zhì)是類共享變量;非靜態(tài)變量是類不共享變量。
- 靜態(tài)const成員變量:類內(nèi)直接初始化,因為貫穿程序的生命周期,且在運行期間數(shù)值不可修改,是綁定在整個類上的變量。
實例4——constexpr修飾構(gòu)造函數(shù)/析構(gòu)函數(shù):
構(gòu)造函數(shù)用constexpr修飾,要么非空要么只涉及基本四則運算和判斷的簡潔函數(shù)體。 析構(gòu)函數(shù)用constexpr修飾,得到的效果是編譯期對象銷毀時沒有運行期開銷。 (constexpr修飾的效果要么是用于設(shè)定真常量,要么是能在編譯期間能處理的事情給處理了。)
class MyInt{
public:
//構(gòu)造函數(shù)
constexpr MyInt (int val_) : val(val_) {}
//析構(gòu)函數(shù)
constexpr ~MyInt() = default; //析構(gòu)函數(shù)直接 = default 就行。
//成員函數(shù)
constexpr int get_val() const {
return val;
}
private:
int val;
};
int main() {
//在編譯期構(gòu)造 MyInt 對象
constexpr MyInt mi(100);
constexpr int val = mi.get_val(); // 編譯期求值為100
return 0;
}
關(guān)聯(lián)說明類成員函數(shù)的const尾綴修飾: constexpr int get_val() const { return val; //這個const成員函數(shù)只讀取,沒有修改val的權(quán)限。 }
const成員函數(shù)
作用是限定這個成員函數(shù)對成員變量的操作權(quán)限僅僅是只讀。
- 禁止修改類的非靜態(tài)成員變量,確保這個函數(shù)只進行只讀操作,不會改變對象的狀態(tài)。
- 禁止調(diào)用非
const成員函數(shù)。
const是 “承諾不修改成員變量”,僅支持運行期執(zhí)行;constexpr是 “支持編譯期求值”,
實例5——constexpr修飾模板template:
使模板實例化后具備編譯器求值能力。
template <template T>
constexpr T max_val(T a, T b){
return a > b ? a : b;
}
int main() {
constexpr int max_num = max_val(5,10);
//編譯期求值: max_val(5,10)實例化得到int型數(shù)據(jù),取值為10.
return 0;
}
到此這篇關(guān)于C++ constexpr的使用小結(jié)的文章就介紹到這了,更多相關(guān)C++ constexpr內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
vscode配置遠程開發(fā)環(huán)境并遠程調(diào)試運行C++代碼的教程
這篇文章主要介紹了vscode配置遠程開發(fā)環(huán)境并遠程調(diào)試運行C++代碼的教程,本文通過截圖實例相結(jié)合給大家介紹的非常詳細,對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友可以參考下2020-04-04
Qt QStandardItemModel用法小結(jié)
QStandardItemModel可用作標(biāo)準(zhǔn)Qt數(shù)據(jù)類型的存儲庫,本文主要介紹了Qt QStandardItemModel用法小結(jié),文中通過示例代碼介紹的非常詳細,對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2023-12-12

