我有一个包含4个构造函数的类,以及如下函数:
using namespace std;
class ABC {
public:
ABC() {
cout << "ABC()\n";
}
ABC(int) {
cout << "ABC(int)\n";
}
ABC(ABC&) {
cout << "ABC(&)\n";
}
ABC(ABC&&) {
cout << "ABC(&&)\n";
}
};
void ff(ABC t) { }
请帮我解释一些对我来说很奇怪的行为(我使用MSVC 2016进行编译):
1)为什么我会收到警告C4930:&#34;&#39; ABC a1(ABC(__ cdecl *)(void))&#39;:未调用原型函数(是否有变量定义?)& #34;使用以下代码:
void main() {
ABC a1(ABC());
ff(ABC(5));
}
在执行时,我希望得到以下输出:
ABC()
ABC(&&)
ABC(int)
ABC(&&)
但我真正得到的是
ABC(int)
2)现在如果我改为
void main() {
ABC a1(ABC(5));
ff(ABC(5));
}
没有更多的警告。但在执行时,我期望得到的是
ABC(int)
ABC(&&)
ABC(int)
ABC(&&)
但我真正得到的是
ABC(int)
ABC(int)
3)现在
void main() {
ABC( ABC() );
ff(ABC(5));
}
它甚至无法编译。我收到错误C2660:&#34;&#39; ABC&#39;:函数不带1个参数&#34;。
4)最后,为什么以下编译而3)没有?
void main() {
ff(ABC(5));
}
答案 0 :(得分:5)
由于问题称为most vexing parse in C++,行
ABC a1(ABC());
将a1
声明为返回类型为ABC
且其参数类型为不带参数的函数并返回ABC
的函数。
该行
ABC(ABC());
更难以剖析,但它也是函数的声明,而不是变量的定义。
int(a);
是变量a
的有效声明。它与:
int a;
同样,ABC
的行与:
ABC ABC();
这里ABC
意味着重载。第一个ABC
是类型名称。第二个ABC
是函数名称(由于最令人烦恼的解析)。它声明ABC
是一个不带参数的函数,并返回类型为ABC
的对象。对于函数的其余部分,ABC
是函数名称,而不是类型名称。因此,
ff(ABC(5));
无效,因为在该上下文中ABC
是一个不带参数的函数。
我没有回答为什么移动构造函数不会被调用的问题。