You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

多参数构造函数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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.28 18:50:33