[英]Is the constexpr specifier required on the declaration of a constexpr static member initialized outside of the class?
C ++17§10.1.5/ 1指出:
constexpr
說明符應僅適用於變量或變量模板的定義或函數或函數模板的聲明。 使用constexpr
說明符聲明的函數或靜態數據成員隱式地是內聯函數或變量(10.1.6)。 如果函數或函數模板的任何聲明都有constexpr
說明符,那么它的所有聲明都應包含constexpr
說明符。
因為類似的段落已在標准中存在C ++ 11(§7.1.5/ 1),這是在引述由理查德·史密斯評論 ,其中他聲稱,C ++標准不需要 constexpr
說明符之間匹配聲明和變量的定義 。 在上段的最后一句明確要求constexpr
符跨功能和函數模板聲明匹配,但沒有提到變量聲明。
§10.1.5/ 9指出:
對象聲明中使用的
constexpr
說明符將對象聲明為const
。 這樣的對象應具有文字類型並應初始化。 在任何constexpr
變量聲明中,初始化的完整表達式應為常量表達式(8.20)。
當然,如果我們有一個單獨的聲明和定義,他們都將需要匹配的const
湖,無論是否constexpr
符都需要相匹配。
§12.2.3.2/ 2-3說:
2在其類定義中聲明非內聯靜態數據成員不是定義,除了cv
void
之外可能是不完整的類型。 未在類定義中內聯定義的靜態數據成員的定義應出現在包含成員類定義的命名空間范圍內。 在命名空間作用域的定義中,靜態數據成員的名稱應使用::運算符通過其類名限定。 靜態數據成員定義中的初始化表達式在其類的范圍內(6.3.7)。3如果非易失性非內聯
const
靜態數據成員具有整數或枚舉類型...如果使用constexpr
說明符聲明該成員,則可以在沒有初始化程序的命名空間范圍內重新聲明該成員(此用法已棄用;請參閱D 0.1)。 其他靜態數據成員的聲明不應指定大括號或等於初始化器 。
§D.1/ 1內容如下:
為了與先前的C ++國際標准兼容,可以在類外部冗余地重新聲明
constexpr
靜態數據成員而不使用初始化程序。 不推薦使用此用法。
從中我們可以收集到,如果使用constexpr
說明符聲明成員,則命名空間范圍定義是多余的, 初始化表達式必須與聲明配對,並且必須從定義 / 重新聲明中省略。
為了作為一個完整的例子,我提供了一個自己的文字類型的靜態成員的情況( 不能在類中初始化):
struct S
{
static S const ZERO; // not marked `constexpr`, but still `const`
constexpr S(int value = {}) : _value{ value } {}
int const _value;
};
constexpr S S::ZERO{ 0 }; // implicitly `inline` (if C++17) and `const`
GCC,Clang和MSVC支持對constexpr
與靜態數據成員一起使用的解釋,盡管我被告知這是錯誤的 。
跨變量聲明和定義使用constexpr
說明符不匹配是違反的嗎?
如果這實際上是違規,則無法正確定義其自己的類的constexpr
靜態數據成員,因為類內定義是禁止的,因為類型不完整,並且禁止類外定義包含初始化程序如果類內聲明用constexpr
說明符標記。
如果我讀這個:
static S const ZERO; // not marked `constexpr`, but still `const`
由於const
S::ZERO
永遠不會在運行時更改其值。
然而:
constexpr S S::ZERO{ 0 }; // implicitly `inline` (if C++17) and `const`
對S::ZERO
進行Constant Evaluation
,對於_value
,它將具有常量整數值0
。
這將調用constexpr constructor
:
constexpr S(int value = {}) : _value{ value } {}
根據basic.start.static - 常量初始化 :
變量或臨時對象的常量初始化器
o
是一個初始化器,其full-expression是一個常量表達式 ,除非o
是一個對象,這樣的初始化器也可以調用o
及其子對象的constexpr構造函數 ,即使這些對象是非對象的-literal類類型。
AND expr.const / 8.7 - 持續評估 :
一個變量,其名稱顯示為潛在的常量計算表達式,該表達式是constexpr變量或者是非易失性const限定的整數類型或引用類型。
因此:
跨變量聲明和定義使用constexpr說明符不匹配是違反的嗎?
我相信你的代碼很好。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.