调用以函数为实参的拷贝构造函数时出现构造不匹配错误,求排查
问题原因分析与解决
你的代码里有两个核心问题导致了「无匹配构造函数」的错误:
1. 经典的函数声明歧义(Most Vexing Parse)
你写的a aa(f());这行代码,编译器会把它解析成函数声明,而不是创建a类型的对象。具体来说,它被解析为:
声明一个名为
aa的函数,返回值类型是a,参数是一个指向「返回a类型、无参数的函数」的指针(刚好和f的类型匹配)。
这完全不是你想要的“用f()的返回值初始化aa”的操作,自然找不到对应的构造函数。
2. 拷贝构造函数的参数类型错误
就算解决了上面的歧义问题(比如改成a aa{f()};或者a aa = f();),原来的自定义拷贝构造函数a(a& x)依然会报错。原因是:
f()返回的是临时对象(右值),C++中,非const的左值引用(a&)无法绑定到右值;- 当你移除自定义拷贝构造函数时,编译器会自动生成默认的拷贝构造函数,它的参数是
const a&——这种const左值引用可以绑定右值,因此不会报错。
修复方案
针对这两个问题,给出两种可行的修复方式:
方式一:修正拷贝构造函数并解决歧义
#include<iostream> #include<string> #include<algorithm> #include<cmath> #include<cctype> #include<iomanip> #include<climits> #include<cstdlib> #include<numeric> #include<vector> #include<utility> #include<set> #include<unordered_set> #include<map> #include<stack> #include<queue> using namespace std; typedef long long ll; class a { public : // 将拷贝构造函数的参数改为const引用 a(const a& x) { cout << 1 << endl; } a() {} }; a f() { a aa; return aa; } int main(void) { ios_base::sync_with_stdio(0), cin.tie(0), cout.tie(0); // 用列表初始化解决歧义,也可以写成a aa = f(); a aa{f()}; return 0; }
方式二:移除自定义拷贝构造函数(如果不需要自定义拷贝逻辑)
让编译器生成默认的拷贝构造函数,同时修正初始化的歧义问题:
#include<iostream> #include<string> #include<algorithm> #include<cmath> #include<cctype> #include<iomanip> #include<climits> #include<cstdlib> #include<numeric> #include<vector> #include<utility> #include<set> #include<unordered_set> #include<map> #include<stack> #include<queue> using namespace std; typedef long long ll; class a { public : a() {} // 移除自定义拷贝构造函数,使用编译器默认生成的版本 }; a f() { a aa; return aa; } int main(void) { ios_base::sync_with_stdio(0), cin.tie(0), cout.tie(0); a aa = f(); // 或者写成a aa{f()}; return 0; }
内容的提问来源于stack exchange,提问作者Mohamad_T
相关产品推荐
相关产品推荐

