更新時(shí)間:2021-08-12 12:14:12 來源:動(dòng)力節(jié)點(diǎn) 瀏覽1012次
定義可以在編譯時(shí)計(jì)算的表達(dá)式。
此類表達(dá)式可用作非類型模板參數(shù)、數(shù)組大小以及其他需要常量表達(dá)式的上下文,例如
整數(shù)n = 1 ;
std:: array < int , n > a1 ; // 錯(cuò)誤:n 不是常量表達(dá)式
const int cn = 2 ;
std:: array < int , cn > a2 ; // OK: cn 是一個(gè)常量表達(dá)式
一個(gè)核心常量表達(dá)式是任何表達(dá)式,其評(píng)價(jià)不會(huì)評(píng)估以下情形之一:
的this指針,除了在constexpr功能正被評(píng)估作為表達(dá)式的一部分
調(diào)用未聲明為constexpr的函數(shù)(或構(gòu)造函數(shù))的函數(shù)調(diào)用表達(dá)式
constexpr int n = std:: numeric_limits < int > :: max ( ) ; // OK: max() 是 constexpr
constexpr int m = std:: time ( nullptr ) ; // 錯(cuò)誤:std::time() 不是 constexpr
對(duì)constexpr已聲明但未定義的函數(shù)調(diào)用
對(duì)constexpr函數(shù)/構(gòu)造函數(shù)模板實(shí)例化的函數(shù)調(diào)用,其中實(shí)例化無法滿足constexpr 函數(shù)/構(gòu)造函數(shù)要求。
(C++20 起)對(duì) constexpr 虛函數(shù)的函數(shù)調(diào)用,在常量表達(dá)式中不可使用的對(duì)象上調(diào)用,并且其生命周期開始于該表達(dá)式之外。
超出實(shí)現(xiàn)定義限制的表達(dá)式
一個(gè)表達(dá)式,其求值會(huì)導(dǎo)致任何形式的核心語(yǔ)言未定義行為(包括有符號(hào)整數(shù)溢出、被零除、數(shù)組邊界外的指針運(yùn)算等)。未指定是否檢測(cè)到標(biāo)準(zhǔn)庫(kù)未定義行為。
constexpr 雙d1 = 2.0 / 1.0 ; // OK
constexpr double d2 = 2.0 / 0.0 ; // 錯(cuò)誤:未定義
constexpr int n = std:: numeric_limits < int > :: max ( ) + 1 ; // 錯(cuò)誤:溢出
int x, y, z [ 30 ] ;
constexpr 自動(dòng)e1 = & y - & x ; // 錯(cuò)誤:未定義的
constexpr auto e2 = & z [ 20 ] - & z [ 3 ] ; // OK
constexpr std:: bitset < 2 > a ;
constexpr bool b = a [ 2 ] ; // UB,但未指定是否檢測(cè)到
(直到 C++17)一個(gè)lambda 表達(dá)式
應(yīng)用于聯(lián)合或其子對(duì)象的非活動(dòng)成員的左值到右值隱式轉(zhuǎn)換或修改(即使它與活動(dòng)成員共享公共初始序列)
(C++20 起)應(yīng)用于具有不確定值的對(duì)象的左值到右值隱式轉(zhuǎn)換
為其活動(dòng)成員(如果有)是可變的聯(lián)合調(diào)用隱式定義的復(fù)制/移動(dòng)構(gòu)造函數(shù)或復(fù)制/移動(dòng)賦值運(yùn)算符,除非聯(lián)合對(duì)象的生命周期在此表達(dá)式的計(jì)算中開始
(C++17 起) (C++20 前)賦值表達(dá)式或重載賦值運(yùn)算符的調(diào)用將改變聯(lián)合的活動(dòng)成員
引用變量或引用類型數(shù)據(jù)成員的id 表達(dá)式,除非該引用可用于常量表達(dá)式或其生命周期在此表達(dá)式的計(jì)算中開始
從簡(jiǎn)歷轉(zhuǎn)換 無效* 任何指向?qū)ο箢愋偷闹羔?/p>
(直到 C++20)dynamic_cast
reinterpret_cast
(直到 C++20)偽析構(gòu)函數(shù)調(diào)用
(C++14 前)自增或自減運(yùn)算符
(C++14 起)對(duì)象的修改,除非該對(duì)象具有非易失性文字類型并且其生命周期在表達(dá)式的求值內(nèi)開始
constexpr int incr ( int & n ) {
return ++ n ;
}
constexpr int g ( int k ) {
constexpr int x = incr ( k ) ; // 錯(cuò)誤:incr(k) 不是核心常量
// 表達(dá)式,因?yàn)?k 的生命周期
// 開始于表達(dá)式 incr(k) 之外
return x ;
}
constexpr int h ( int k ) {
int x= incr ( k ) ; // OK: x 不需要用核心初始化
// 常量表達(dá)式
return x ;
}
constexpr int y = h ( 1 ) ; // OK:用值 2 初始化 y
// h(1) 是一個(gè)核心常量表達(dá)式,因?yàn)?
// k 的生命周期從表達(dá)式 h(1) 內(nèi)部開始
(直至C ++ 20)一個(gè)typeid施加到多態(tài)型的一個(gè)glvalue表達(dá)
一個(gè)new-expression ,除非選定的分配函數(shù)是一個(gè)可替換的全局分配函數(shù)并且分配的存儲(chǔ)在此表達(dá)式的計(jì)算中被釋放 (C++20 起)
一個(gè)delete-expression ,除非它解除分配在此 expession 的計(jì)算中分配的存儲(chǔ)區(qū)域 (C++20 起)
(C++20 起)對(duì)std::allocator::allocate的調(diào)用,除非已分配的存儲(chǔ)在此表達(dá)式的計(jì)算中被釋放
(C++20 起)對(duì)std::allocator::deallocate的調(diào)用,除非它解除分配在此 expession 求值內(nèi)分配的存儲(chǔ)區(qū)域
(因?yàn)镃 ++ 20)的AWAIT表達(dá)或產(chǎn)量表達(dá)
(因?yàn)镃 ++ 20)一個(gè)三通比較時(shí)的結(jié)果是不確定的
結(jié)果未指定時(shí)的等式或關(guān)系運(yùn)算符
(C++14 前)賦值或復(fù)合賦值運(yùn)算符
拋出表達(dá)式
(因?yàn)镃 ++ 20)的ASM-聲明
(因?yàn)镃 ++ 14)所述的調(diào)用的va_arg宏時(shí),的調(diào)用是否的va_start宏可以評(píng)估是未指定的
(C++20 起)會(huì)拋出異常的dynamic_castortypeid表達(dá)式
在 lambda 表達(dá)式內(nèi)部,this對(duì)該 lambda 外部定義的變量的引用或引用,如果該引用將是 odr 使用
void g ( ) {
const int n = 0 ;
constexpr int j = * & n ; // OK:在 lambda 表達(dá)式之外
[ = ] { constexpr int i = n ; // OK: 'n' 不是 odr 使用的,也沒有在這里捕獲。
constexpr int j = * & n ; // 格式錯(cuò)誤:'&n' 將是 'n' 的 odr 使用。
} ;
}
甲常量表達(dá)式是任一
左值 (C++14 前)泛 左值(C++14起)核心常量表達(dá)式,它指的是
具有非臨時(shí)靜態(tài)存儲(chǔ)持續(xù)時(shí)間的對(duì)象,或
具有靜態(tài)存儲(chǔ)持續(xù)時(shí)間的臨時(shí)對(duì)象,但其值滿足以下純右值的約束,或
(C++14 起)
一個(gè)非即時(shí) (因?yàn)镃 ++ 20)功能
一個(gè)純右值核心常量表達(dá)式,其值滿足以下約束:
如果該值是類類型的對(duì)象,引用類型的每個(gè)非靜態(tài)數(shù)據(jù)成員是指實(shí)體滿足用于約束的左值 (直到C ++ 14) glvalues (因?yàn)镃 ++ 14)以上
如果值是指針類型,它持有
具有靜態(tài)存儲(chǔ)期的對(duì)象的地址
超過具有靜態(tài)存儲(chǔ)持續(xù)時(shí)間的對(duì)象末尾的地址
一的地址非即時(shí) (因?yàn)镃 ++ 20)功能
空指針值
如果值是指向成員函數(shù)的指針類型,則不指定立即函數(shù)
(C++20 起)
如果值是類或數(shù)組類型的對(duì)象,則每個(gè)子對(duì)象都滿足這些值的約束
積分常數(shù)表達(dá)式
整型常量表達(dá)式是隱式轉(zhuǎn)換為純右值的整型或無作用域枚舉類型的表達(dá)式,其中轉(zhuǎn)換后的表達(dá)式為核心常量表達(dá)式。如果在需要整型常量表達(dá)式的地方使用類類型的表達(dá)式,則該表達(dá)式會(huì)在上下文中隱式轉(zhuǎn)換為整型或無作用域枚舉類型。
以下上下文需要整數(shù)常量表達(dá)式:
數(shù)組邊界
new 表達(dá)式中除第一個(gè)以外的 維度
(直到 C++14)
位域長(zhǎng)度
基礎(chǔ)類型不固定時(shí)的枚舉初始值設(shè)定項(xiàng)
對(duì)齊方式。
轉(zhuǎn)換后的常量表達(dá)式
甲轉(zhuǎn)換常量表達(dá)式類型T是一個(gè)表達(dá)式隱式轉(zhuǎn)換為類型T,其中,所述轉(zhuǎn)換后的表達(dá)式是一個(gè)常量表達(dá)式,并且隱式轉(zhuǎn)換序列只包含:
constexpr 用戶定義的轉(zhuǎn)換(因此可以在需要整數(shù)類型的地方使用類)
左值到右值的轉(zhuǎn)換
積分促銷
非縮小積分轉(zhuǎn)換
以下表達(dá)式或轉(zhuǎn)換可能是常量評(píng)估:
明顯的常量評(píng)估表達(dá)式
潛在評(píng)估表達(dá)式
花括號(hào)初始化器列表的直接子表達(dá)式(可能需要不斷評(píng)估以確定轉(zhuǎn)換是否正在縮小)
address-of (unary &) 出現(xiàn)在模板化實(shí)體中的表達(dá)式(可能需要不斷求值來確定這樣的表達(dá)式是否依賴于值)
上述之一的子表達(dá)式不是嵌套未計(jì)算操作數(shù)的子表達(dá)式
如果函數(shù)是constexpr 函數(shù)并由可能是常量求值的表達(dá)式命名,則需要該函數(shù)進(jìn)行常量求值。
如果變量是constexpr 變量,或者是非易失性 const 限定的整數(shù)類型或引用類型,并且表示它可能是常量評(píng)估的id 表達(dá)式,則需要一個(gè)變量來進(jìn)行常量評(píng)估。
一個(gè)默認(rèn)的功能和實(shí)例化的定義函數(shù)模板專業(yè)化或可變模板專業(yè)化 (因?yàn)镃 ++ 14)如果該功能被觸發(fā)的或可變的 (因?yàn)镃 ++ 14)需要用于恒定評(píng)估。
以上就是動(dòng)力節(jié)點(diǎn)小編介紹的"常量表達(dá)式詳解",希望對(duì)大家有幫助,想了解更多可查看Java在線學(xué)習(xí)。動(dòng)力節(jié)點(diǎn)在線學(xué)習(xí)教程,針對(duì)沒有任何Java基礎(chǔ)的讀者學(xué)習(xí),讓你從入門到精通,主要介紹了一些Java基礎(chǔ)的核心知識(shí),讓同學(xué)們更好更方便的學(xué)習(xí)和了解Java編程,感興趣的同學(xué)可以關(guān)注一下。
0基礎(chǔ) 0學(xué)費(fèi) 15天面授
有基礎(chǔ) 直達(dá)就業(yè)
業(yè)余時(shí)間 高薪轉(zhuǎn)行
工作1~3年,加薪神器
工作3~5年,晉升架構(gòu)
提交申請(qǐng)后,顧問老師會(huì)電話與您溝通安排學(xué)習(xí)
初級(jí) 202925
初級(jí) 203221
初級(jí) 202629
初級(jí) 203743