[英]Designated initializer different behavior before and after c++20
我遇到了這種奇怪的行為,我找不到很好的解釋。
下面的代碼將在 c++20 之前編譯成功,並且只有在使用explicit
時才會失敗。
struct Square {
int area = 10;
Square() = default; // only if this is explicit will the compile fail
Square(const Square& other) = delete;
Square(Square&& other) = delete;
Square& operator =(Square&& square) = delete;
Square& operator =(const Square& square) = delete;
};
int main() {
Square s = {
.area = 10
};
}
這本身就很奇怪,但是將編譯器轉換為 c++20 會使上述代碼失敗並顯示這些錯誤消息
gcc
無法轉換大括號括起來的初始值設定項列表
clang
'Square' 的初始化沒有匹配的構造函數
問題:
為什么它在 c++20 之前編譯成功,除非explicit
? 換句話說,發生了什么隱式轉換來實現這一點?
c++20 中的哪些變化導致此代碼無法編譯?
為什么在c++20之前編譯成功...
該程序在 C++20 之前格式不正確。
在 C++20 之前的語言中不存在指定初始化器。 由於語言擴展,它可以編譯。
c++20 中的哪些變化使它不再編譯?
該程序在 C++20 中的格式仍然不正確。
在 C++20 中,指定的初始化程序被引入到該語言中,看起來規則與語言擴展所做的略有不同。 相關規則是(來自最新草案):
[dcl.init.list] object 或 T 類型引用的列表初始化定義如下:
如果花括號初始化列表包含指定初始化列表,則 T 應為聚合 class。 ...
...
[dcl.init.aggr] 聚合是一個數組或一個 class ([class])
沒有用戶聲明或繼承的構造函數([class.ctor]),
...
正如NathanOliver所解釋的,C++20 之前語言擴展的行為差異可能與聚合定義的變化有關
在 C++20 中,您的 class 不再是聚合。 由於它不是聚合,因此您不能使用指定的初始化程序。 此更改是P1008的結果,它刪除了用戶提供的默認或已刪除構造函數作為聚合的資格。 為什么需要進行此更改的示例是:
struct X {
int i{4};
X() = default;
};
int main() {
X x1(3); // ill-formed - no matching c’tor
X x2{3}; // compiles!
}
其中X x2{3}
不應該編譯,但它確實是因為X() = default;
並不能阻止它成為一個聚合體。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.