11

可能重复:
为什么使用空括号调用不带参数的构造函数是错误的?

让我们有这个代码

class Foo {
  Foo(int) { }
};

然后我们有结果:

int main() {
  Foo f1 = Foo(5); // 1: OK, explicit call
  Foo f2(5); // 2: OK, implicit call
  Foo f3(); // 3: no error, "f3 is a non-class type Foo()", how so?
  Foo f4(f1); // 4: OK, implicit call to default copy constructor
  Foo f5; // 5: expected error: empty constructor missing
}

您能解释一下案例3中发生了什么吗?

4

6 回答 6

12

第三行被解析为声明一个不带参数并返回 a 的函数Foo

于 2011-12-12T14:32:05.277 回答
8

Foo f3();声明一个名为 的函数f3,返回类型为Foo.

于 2011-12-12T14:32:12.500 回答
5

C++ 有一个规则,如果一个语句可以被解释为一个函数声明,它就会以这种方式被解释。

因此,语法Foo f3();实际上声明了一个不带参数并返回的函数 Foo。通过编写来解决这个问题Foo f3;,它也会调用默认构造函数(当然,如果有的话)。

于 2011-12-12T14:33:23.773 回答
4
  • f1在显式调用后调用复制构造函数,你错了
  • f2是一个显式的构造函数调用 // 你在这里也错了
  • f3声明一个函数
  • f4再次是复制构造函数,就像f1// 你在这里
  • f5会调用默认构造函数 // 你又来了
于 2011-12-12T14:33:43.257 回答
3

这不是你想的那样:

 Foo f3();

您可能认为这是对默认构造函数的显式调用,但事实并非如此。它实际上是一个名为的函数的声明,f3它不带参数并按Foo值返回。

将 this 解析为函数声明而不是构造函数调用被称为Most Vexing Parse

于 2011-12-12T14:35:11.400 回答
2

您已经定义了一个名为 f3 的函数,它在案例 3 中返回一个 foo。在案例 5 中,您没有定义默认构造函数,因此您会收到错误消息。

于 2011-12-12T14:33:02.847 回答