std::initializer_list
由編譯器從大括號括起來的init列表構造而成,並且此列表的大小必須是編譯時間常量。爲什麼大小不是std :: initializer_list的模板參數?
那麼爲什麼委員會決定從模板參數中省略大小呢?這可能會阻止某些優化並使某些事情不可行(從std::initializer_list
初始化std::array
)。
std::initializer_list
由編譯器從大括號括起來的init列表構造而成,並且此列表的大小必須是編譯時間常量。爲什麼大小不是std :: initializer_list的模板參數?
那麼爲什麼委員會決定從模板參數中省略大小呢?這可能會阻止某些優化並使某些事情不可行(從std::initializer_list
初始化std::array
)。
現有系統的一個優點是可以導出從DLL中取出initializer_list
的函數。如果它是根據尺寸模板化的,則必須將其作爲源代碼進行發貨。
沿着同樣的路線:它可能會導致一些不平凡的膨脹。 – MSalters
如果initializer_list
被定義爲std::initializer_list<type, size>
,然後任何函數,它的initializer_list<type>
,其中type
是一些具體的類型,現在就必須根據該列表的大小的模板功能。或者他們將不得不要求用戶通過的特定類型的initializer_list
並且尺寸爲。
這兩個都是非常不可接受的。並非所有人都將他們的代碼編寫爲模板。
您可以從braced-init-list({}
中間的東西)初始化一個std::array
。但這與std::intiializer_list
不一樣。 array
類是一個聚合類型。它是一個包含單個元素的結構,它是一個公共數組。因此,在一個符合C++ 11個實施方式中,這應該編譯:
std::array<int, 3> myArray = {1, 3, 5};
然而,{1, 3, 5}
不是std::initializer_list
對象;它只是一個braced-init-list,可以用來初始化適當的類型。
您不能std::initializer_list
對象傳遞給aggegate的構造函數(因爲聚集有沒有構造函數),但你可以使用一個支撐,初始化列表來調用集合初始化,初始化std::array
,就像你對任何結構包含一個數組。
std::initializer_list
與加載初始化列表之間的區別有點像int
和字面0
之間的區別。將(int
)對象隱式轉換爲指針類型並不是(通常)合法的,但將整數文字0隱式轉換爲指針類型是合法的。方式支撐-INIT-名單的工作是這樣的:
int i = 0; //Legal
void *j = 0; //Legal
void *k = i; //Not legal
std::array<int, 3> myArray = {1, 3, 5}; //Legal
std::initializer_list<int> myInitList = {1, 3, 5}; //Legal
std::array<int, 3> myArray = myInitList; //Not legal
一個非常類似的問題是: 「爲什麼'的std :: initializer_list :: size'不'constexpr'(了)?」這是一年前在clC++ m上提出的。 – MSalters
Re MSalters'2011評論,請注意,即使C++ 11沒有,C++ 14 *也會使std :: initializer_list :: size成爲'constexpr'函數。 http://en.cppreference.com/w/cpp/utility/initializer_list/size – Quuxplusone