![](/img/trans.png)
[英]Struct non-type template parameter + agregate initialization: standard in c++20 or not
[英]What does the C++20 standard say about usage of subojects as template non-type arguments?
“模板參數和模板參數”一文的“ 模板非類型 arguments ”段落指出:
唯一的例外是 class 類型的非類型模板參數及其子對象(C++20 起)中引用或指針類型的非類型模板參數和引用或指針類型的非靜態數據成員不能引用/是地址
- 一個臨時的 object(包括在參考初始化期間創建的一個);
- 字符串文字;
typeid
的結果;- 預定義變量
__func__
;- 或上述之一的子對象(包括非靜態 class 成員、基礎子對象或數組元素) (C++20 起) 。
重點是我的。
下面有一個例子
template<int* p> class X {};
int a[10];
struct S
{
int m;
static int s;
} s;
X<&a[2]> x3; // error: address of array element
X<&s.m> x4; // error: address of non-static member
X<&s.s> x5; // ok: address of static member
X<&S::s> x6; // ok: address of static member
根據引用的語句,注釋中帶有單詞error
的行應該可以由支持 c++20 的 c++ 編譯器編譯,因為a[2]
和sm
既不是臨時對象,也不是字符串文字,也不是typeid
或預定義變量的結果__func__
也以上之一的子對象。 實際上,gcc 11.1 編譯代碼沒有錯誤,但是 clang 12.0.0 編譯代碼有錯誤。
此外,N4835 草案在第 13.4.2 段中聲明了以下內容
非類型模板參數的模板參數應是模板參數類型的轉換常量表達式(7.7)。 對於引用或指針類型的非類型模板參數,或 class 類型的非類型模板參數或其子對象中的每個引用或指針類型的非靜態數據成員,引用或指針值不應引用到或成為(分別)的地址:
- 一個子對象(6.7.2),
- 一個臨時的 object (6.7.7),
- 字符串文字 (5.13.5),-(2.4)
typeid
表達式 (7.6.1.7) 的結果,或- 預定義的
__func__
變量 (9.5.1)。
並包含上述示例。 再次強調是我的。
考慮到這個草案,clang 可以正常工作,而 gcc 不能,因為a[2]
和sm
是子對象。
深層發掘。 N4878 草案在第 13.4.3 段中包含以下文本
對於引用或指針類型的非類型模板參數,或 class 類型的非類型模板參數或其子對象中的每個引用或指針類型的非靜態數據成員,引用或指針值不應引用到或成為(分別)的地址:
- 一個臨時的 object (6.7.7),
- 字符串文字 object (5.13.5),
typeid
表達式 (7.6.1.8) 的結果,- 預定義的
__func__
變量(9.5.1),或- 上述之一的子對象(6.7.2)。
並且不包含示例。
本主題開頭引用的文本對應於草案 N4878,因此 gcc 可以正常工作,而 clang 不能正常工作。
C++20標准對使用子對象作為模板非類型 arguments 有什么看法? 哪個編譯器符合標准?
措辭作為P1907R1的一部分進行了更改,后者被作為 C++20 的一部分采用。 請注意,您引用的第一稿 - N4835 - 早於本次采用(該草案於 2019 年 10 月發布,本論文於次月在 2019 年 11 月的貝爾法斯特會議上獲得通過)。 最接近 C++20 的草案是N4861 ,您也可以方便地以html 形式查看。
結果如下:
template<int* p> class X {};
int a[10];
struct S
{
int m;
static int s;
} s;
X<&a[2]> x3;
X<&s.m> x4;
是一個有效的 C++20 程序,因為a[2]
和sm
都不是以下任何項的子對象:臨時、字符串文字、 typeid
表達式的結果或__func__
。
cppreference 示例已經更新以反映這一點,現在的評論如下:
X<&a[2]> x3; // error (until C++20): address of array element
X<&s.m> x4; // error (until C++20): address of non-static member
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.