多参数构造函数explicit关键字疑问:编译结果与预期不符
关于C++列表初始化中initializer_list构造函数的匹配疑问
#include <iostream> using namespace std; class P { public: P(int a, int b) { cout << "P(int a, int b)" << endl; } P(initializer_list<int>) { cout << "P(initializer_list<int>)" << endl; } explicit P(int a, int b, int c) { cout << "explicit P(int a, int b, int c)" << endl; } }; void fp(const P&) { } int main(){ P p1(77, 5); //P(int a, int b) P p2{ 77,5 }; //P(initializer_list<int>) P p3{ 77,5,42 };//P(initializer_list<int>) P p4 = { 77, 5};//P(initializer_list<int>) P p5 = { 77,5,42 };//P(initializer_list<int>) P p6(77, 5, 42);//explicit P(int a, int b, int c) cout << "---------------------------" << endl; fp({ 47,11 });//P(initializer_list<int>) fp({ 47,11,3 });//P(initializer_list<int>) fp(P{ 47,11 });//P(initializer_list<int>) fp(P{ 47,11,3 });//P(initializer_list<int>) cout << "---------------------------" << endl; P p11{ 77,5,42,500 };//P(initializer_list<int>) P p12 = { 77, 5, 42, 500 };//P(initializer_list<int>) P p13{ 10 };//P(initializer_list<int>) cout<<__cplusplus<<endl;//201103 return 0; }
你觉得P p5 = {77,5,42};和fp({47,11,3});会报错,核心是没掌握C++11及以后列表初始化的优先级规则:
- 当类中定义了**
initializer_list类型参数的构造函数**时,只要列表中的元素能隐式转换为initializer_list的元素类型(这里都是int,完全匹配),所有列表初始化形式(包括=拷贝初始化、直接列表初始化、函数参数的列表初始化)都会优先选择这个构造函数,不管列表里元素的数量多少。 - 对于
P p5 = {77,5,42};:这是拷贝初始化,而你定义的三参数构造是explicit的,explicit构造函数本来就不能用于拷贝初始化(会被排除在候选之外);就算它不是explicit,因为存在initializer_list构造,编译器也会优先选后者。 - 对于
fp({47,11,3});:函数参数需要const P&,编译器会尝试用列表初始化构造临时P对象。同样因为initializer_list构造的优先级更高,直接用它创建临时对象,不会尝试匹配三参数构造。 - 而
P p6(77,5,42);是普通圆括号直接初始化,这种情况不会触发initializer_list构造的优先级规则,编译器会匹配最符合的三参数构造,所以调用了那个explicit版本。
内容的提问来源于stack exchange,提问作者tony
相关产品推荐
相关产品推荐

