[英]Why does an explicitly declared constructor prevent member initialisation with a C++ 11 initialisation list?
我想用這樣的初始化列表初始化一個結構:
struct S
{
int a;
int b;
// S() : a(0), b(0){} // uncommenting will cause compile error:
// error C2440: 'initializing' : cannot convert from 'initializer-list' to 'S'
// S(int aArg, int bArg) : a(aArg), b(bArg) {} // adding this removes the error
}
int main()
{
S s{1,2}; // initialise with list
}
有一個很好的理由,為什么顯式聲明的默認構造函數會導致錯誤? 我認為初始化列表的位置是為了避免程序員編寫像第二個構造函數這樣繁瑣的代碼。
聚合初始化 - 顧名思義 - 僅適用於聚合。 向類中添加一個非平凡的構造函數使其成為非聚合的。 [dcl.init.list] / 3:
列表初始化對象或類型T的引用定義如下:
- 如果初始化列表沒有元素且T是具有默認構造函數的類類型,則對象將進行值初始化。
- 否則,如果T是聚合,則執行聚合初始化(8.5.1)。
- 除此以外, […]
和
聚合是一個數組或類(第9條), 沒有用戶提供的構造函數 (12.1),[...]
當初始化程序列表初始化聚合時,如8.5.4中所述,初始化程序列表的元素將作為聚合成員的初始化程序,增加下標或成員順序。
一旦您的類不再是聚合,list-initialization將查找要調用的構造函數,而不是要初始化的成員。
原因很簡單:如果一個類有非平凡的構造函數,那么有效初始化該類類型的對象的唯一方法是調用該對象的一個構造函數。 在沒有相應構造函數的情況下初始化類對象將是一個毀滅性的設計失敗。
假設它是顯式定義的構造函數,它將初始化結構。 因此,當使用初始化列表時,編譯器會搜索適當的構造函數。 正如您已經指出的那樣,如果要聲明一個帶有兩個int類型參數的構造函數,那么您可以使用初始化列表來初始化結構的數據成員,因為將調用此構造函數。 或者你可以提供一個構造函數,它有一個std :: initializer_list類型的參數。
例如
S( std::initializer_list<int> );
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.