构造函数解释为函数调用,并显式跳过移动构造函数



我有一个有 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:"'ABC a1(ABC (__cdecl *((void((':未调用原型函数(是否打算定义变量?

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:"'ABC':函数不接受 1 个参数"。

4(最后,为什么下面的编译而3(没有?

void main() {
ff(ABC(5));
}

由于被称为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是一个不带参数的函数。


对于为什么不调用移动构造函数的问题,我没有答案。

最新更新