[英]initializer_list, constructors and braced initialization
在閱讀有關不同類型的初始化,我偶然發現的眾多怪異的交互的一個std::initializer_list
(以前的帖子在這里 )。 這顯然是一個簡單的主題,這是C ++書籍中介紹std::vector
的第一個主題。
關鍵是,如果您有一個采用(僅我猜) std::initializer_list
構造std::initializer_list
,則在進行std::initializer_list
時將強烈建議使用該構造函數:換句話說, std::vector<int> NewVect{5, 10}
將創建一個包含5和10的對象,而不是初始化為10的5個元素( std::vector<int> NewVect(5, 10)
)。
auto
括號初始化會發生特殊行為( auto A={1,2,3}
會被推導為std::initializer_list<int>
)。 現在,我不敢相信C ++會為特定的對象提供特殊的處理方式,因為據我所知,標頭只是寫得很好且有用的代碼段。 而且,即使您不直接或間接#include <initializer_list>
,這些語法也不起作用,即使我的編譯器VS2017會打印出一組非常特殊的錯誤,指出需要該標頭才能工作(您可以輕松測試這與auto
)。
所以,我的問題是,這是理所當然的,這是初始化列表標題中代碼的作用,而我的編譯器可能是假定使用STD而構建的,它是如何實現的? 我是否可以重新路由此行為,以免除顯式調用之外再也不會發生(即std::vector<int> NewVect{5, 10}
等同於std::vector<int> NewVect(5, 10)
,您需要現在調用std::vector<int> NewVect{std::initializer_list<int>{5, 10}}
)嗎? 可以將這種行為賦予其他用戶創建的類嗎?
理所當然的是,這種行為是initiliazer列表頭中代碼的影響,而我的編譯器可能是假定使用STD而構建的,它是如何實現的?
標准中有一條特殊的規則,其內容大致如下: “如果您使用列表初始化( {...}
)來構造對象,並且該對象具有采用std::initializer_list
的構造std::initializer_list
,則無論重載分辨率如何 ,都選擇構造函數” 。 這意味着在使用{...}
初始化語法時, std::initializer_list
構造函數始終比其他構造函數具有優先級。
我能否將這種行為重新路由到除顯式調用之外再也不會發生
在您的類中,可以避免使用std::initializer_list
。 那么這種行為將永遠不會發生。 您不能為std::
類更改此設置。
可以將這種行為賦予其他用戶創建的類嗎?
不符合您期望的語法,因為std::initializer_list
很特殊。 您可以創建自己的initializer_list
替代方案,或使用可變參數模板構造函數之類的方法來強制用戶使用顯式語法。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.