C++ std::初始值设定项\列表类型推断

C++ std::初始值设定项\列表类型推断,c++,c++11,initializer-list,type-deduction,list-initialization,C++,C++11,Initializer List,Type Deduction,List Initialization,最近我写了一个非常简单的类 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} });

最近我写了一个非常简单的类

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;
 }
C类
{
公众:
void AddString(std::初始值设定项\u列表x)
{
//无关的
}
};
int main()
{
C C;
c、 AddString({“1”,1},{“2”,2},{“3”,3});
..//其他不重要的东西
返回0;
}
令我惊喜的是,它编译正确,工作正常。有人能给我解释一下编译器是如何推导出
std::pair
的嵌套括号初始值设定项的吗?我正在使用MSVS2013

c.AddString({ {"1",1}, {"2", 2}, {"3", 3} });
您正在向
AddString
传递一个大括号初始化列表,该列表本身包含嵌套的大括号初始化列表。如果内部带括号的init列表可以转换为
std::pair
,则参数可以与
std::initializer\u list
参数匹配

过载解决过程分两步进行;首先,尝试匹配采用
std::initializer\u list
参数的
std::pair
构造函数。由于没有这样的构造函数,因此发生第二步,其中
std::pair
的其他构造函数以
char const[2]
int
作为参数进行枚举。这将匹配以下
构造函数,因为
字符常量[2]
隐式转换为
字符常量*
,而构造函数本身不是
显式

template< class U1, class U2 >
constexpr pair( U1&& x, U2&& y );
模板
constexpr对(U1&x,U2&y);

引用N3337§13.3.1.7/1[超过匹配列表]

当初始化非聚合类类型
T
的对象时(8.5.4),重载解析将分两个阶段选择构造函数:
-最初,候选函数是类
T
的初始值设定项列表构造函数(8.5.4),参数列表由初始值设定项列表作为单个参数组成。
-如果未找到可行的初始值设定项列表构造函数,则再次执行重载解析,其中候选函数是类
T
的所有构造函数,参数列表由初始值设定项列表的元素组成

如果初始值设定项列表没有元素且
T
具有默认构造函数,则省略第一阶段在复制列表初始化中,如果选择了
显式
构造函数,则初始化格式不正确


回答得很好,更加完整!谢谢,这澄清了一些事情。我需要更多地了解有关使用大括号的初始化列表时的重载解析。@PebbleOn每个涉及列表初始化时的重载解析规则是我复制粘贴在上面的。如果你的意思是你需要熟悉一般的重载解析,我建议你从(如果你有时间的话,看整个系列)开始。