C++构造函数匹配错误:添加非const拷贝构造函数为何编译失败?
问题原因解析
核心行为:拷贝初始化的本质
Point p = Point(1, 2);属于拷贝初始化,逻辑上是用Point(1,2)生成的临时匿名对象作为参数,调用拷贝构造函数来初始化p。
分场景拆解:
仅保留带默认参数的构造函数时
你没有自定义拷贝构造函数,编译器会自动生成一个默认拷贝构造函数,签名为Point(const Point&)。const左值引用的特性是可以绑定到右值(临时对象),因此拷贝初始化能正常匹配这个构造函数,编译通过。添加非const引用的拷贝构造函数后
一旦你自定义了拷贝构造函数,编译器就不会再生成默认版本。你写的Point(Point&)构造函数参数是非const左值引用,而C++明确规定:临时对象(右值)不能绑定到非const的左值引用——这是语言层面的安全限制,避免开发者修改毫无意义的临时对象(临时对象会立即销毁,修改结果无法保留)。
此时编译器找不到能接受临时对象的拷贝构造函数,就会抛出no matching function for call toPoint::Point(Point)``的错误。添加const引用的拷贝构造函数后
自定义的Point(const Point&)构造函数参数是const左值引用,它可以合法绑定到右值(临时对象),因此拷贝初始化能正常匹配该构造函数,编译顺利通过。
额外补充
在C17及以后的标准中,Point p = Point(1, 2);会被编译器优化为直接构造(省略拷贝步骤,相当于Point p(1,2);),但如果你的编译标准低于C17,拷贝构造的逻辑依然会触发,上述规则同样适用。
内容的提问来源于stack exchange,提问作者pdemal
相关产品推荐
相关产品推荐

