kie*_*ien 2 c++ constructor most-vexing-parse move-constructor
我有一个包含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) { }
Run Code Online (Sandbox Code Playgroud)
请帮我解释一些对我来说很奇怪的行为(我使用MSVC 2016进行编译):
1)为什么我收到警告C4930:"'ABC a1(ABC(__ cdecl*)(void))':未调用prototyped函数(是一个变量定义?)",使用以下代码:
void main() {
ABC a1(ABC());
ff(ABC(5));
}
Run Code Online (Sandbox Code Playgroud)
在执行时,我希望得到以下输出:
ABC()
ABC(&&)
ABC(int)
ABC(&&)
Run Code Online (Sandbox Code Playgroud)
但我真正得到的是
ABC(int)
Run Code Online (Sandbox Code Playgroud)
2)现在,如果我改为
void main() {
ABC a1(ABC(5));
ff(ABC(5));
}
Run Code Online (Sandbox Code Playgroud)
没有更多的警告.但在执行时,我期望得到的是
ABC(int)
ABC(&&)
ABC(int)
ABC(&&)
Run Code Online (Sandbox Code Playgroud)
但我真正得到的是
ABC(int)
ABC(int)
Run Code Online (Sandbox Code Playgroud)
3)现在
void main() {
ABC( ABC() );
ff(ABC(5));
}
Run Code Online (Sandbox Code Playgroud)
它甚至不编译.我得到错误C2660:"'ABC':函数不带1个参数".
4)最后,为什么以下编译而3)没有?
void main() {
ff(ABC(5));
}
Run Code Online (Sandbox Code Playgroud)
由于这个问题被称为C++中最令人烦恼的解析,所以该行
ABC a1(ABC());
Run Code Online (Sandbox Code Playgroud)
声明a1是一个返回类型ABC为的函数,其参数类型是一个不带参数并返回的函数ABC.
这条线
ABC(ABC());
Run Code Online (Sandbox Code Playgroud)
是一个更难解剖,但它也是一个函数的声明,而不是变量的定义.
int(a);
Run Code Online (Sandbox Code Playgroud)
是变量的有效声明a.它与:
int a;
Run Code Online (Sandbox Code Playgroud)
同样,该行与以下ABC相同:
ABC ABC();
Run Code Online (Sandbox Code Playgroud)
这里ABC有重载的含义.第一个ABC是类型名称.第二个ABC是函数名称(由于最令人烦恼的解析).它声明ABC是一个不带参数的函数,并返回一个类型的对象ABC.对于函数的其余部分,ABC是函数名称,而不是类型名称.所以,
ff(ABC(5));
Run Code Online (Sandbox Code Playgroud)
是无效的,因为在该上下文中ABC是一个不带参数的函数.
我没有回答为什么移动构造函数不被调用的问题.
| 归档时间: |
|
| 查看次数: |
100 次 |
| 最近记录: |