c.AddString({ {"1",1}, {"2", 2}, {"3", 3} });
您正在将一个自包含的
大括号初始化列表作为参数传递给
AddString
函数,该列表本身包含嵌套的
大括号初始化列表。如果内部的
大括号初始化列表可以转换为
std::pair<const char*,int>
,则该参数可以匹配
std::initializer_list<std::pair<const char*,int>>
参数。
这种重载决议过程分为两步进行;首先尝试匹配以std::initializer_list
参数为形参的std::pair
构造函数。由于std::pair
没有这样的构造函数,因此进行第二步,枚举使用char const[2]
和int
作为实参的std::pair<const char*,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 有默认构造函数,则省略第一阶段。在复制列表初始化中,如果选择了一个显式构造函数,则初始化是不合法的。