[英]std::initializer_list type deduction
最近我寫了一個非常簡單的課。
class C
{
public:
void AddString(std::initializer_list<std::pair<const char*,int>> x)
{
//irrelevant
}
};
int main()
{
C c;
c.AddString({ {"1",1}, {"2", 2}, {"3", 3} });
.... //other unimportant stuff
return 0;
}
令我驚喜的是,它編譯並正常工作。 有人可以向我解釋一下編譯器如何能夠推斷出嵌套的支撐初始化器是針對std::pair
嗎? 我正在使用MSVS 2013。
c.AddString({ {"1",1}, {"2", 2}, {"3", 3} });
您正在傳遞一個braced-init-list ,它本身包含嵌套的brace-init-list s到AddString
。 如果內部braced-init-list s可以轉換為std::pair<const char*,int>
該參數可以匹配std::initializer_list<std::pair<const char*,int>>
參數。
這個過載分辨過程分兩步進行; 首先嘗試匹配帶有std::initializer_list
參數的std::pair
構造函數。 由於std::pair
沒有這樣的構造函數,所以第二步發生,其中std::pair<const char*,int>
的其他構造std::pair<const char*,int>
用char const[2]
枚舉, int
作為參數。 這將匹配以下pair
構造函數,因為char const[2]
可以隱式轉換為char const *
,並且構造函數本身不是explicit
。
template< class U1, class U2 >
constexpr pair( U1&& x, U2&& y );
引用N3337§13.3.1.7 / 1 [over.match.list]
當非聚合類類型
T
被列表初始化(8.5.4)時,重載決策分兩個階段選擇構造函數:
- 最初,候選函數是類T
的初始化列表構造函數(8.5.4),參數列表由初始化列表作為單個參數組成。
- 如果找不到可行的初始化列表構造函數,則再次執行重載解析,其中候選函數是類T
所有構造函數,參數列表由初始化列表的元素組成。如果初始化列表沒有元素且
T
具有默認構造函數,則省略第一個階段。 在copy-list-initialization中,如果選擇了explicit
構造函數,則初始化是錯誤的 。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.