声明"vector<int> myvector()"做什么?(关于无参数构造函数的混淆)

What does the statement "vector<int> myvector()" do? (confusion regarding parameterless constructor)

本文关键字:参数 于无 构造函数 什么 int vector gt myvector 声明 lt      更新时间:2023-10-16

我希望有人能澄清我对尝试使用无参数构造函数的语法的困惑。现在,我认为正确的语法要么没有括号:

foo myfoo;
vector<int> myvector;

或者,用括号,但像这样:

foo myfoo = foo();
vector<int> myvector = vector<int>();

但是,编译器不会抱怨这种形式:

foo myfoo();
vector<int> myvector();

然而,当我试图引用"myfoo"或"myvector"的成员时,它随后会抱怨:

myvector.push_back(1);  // "Error: expression must have class type"

因此,我从上面了解到,形式someClass someInstance()并没有做我期望的事情(即,使用无参数构造函数实例化对象),但它确实做了一些的事情。那么它到底是干什么的呢?

这不是构造对象的有效方法。如果您试图通过键入来调用无参数构造函数

MyType mytype();

编译器将其解释为一个名为mytype的函数的声明,该函数返回MyType并且不接受任何参数。由于编译器认为我们在声明一个函数,因此随后将mytype视为对象的尝试将失败。

这被称为"最Vexing解析",因为它的微妙;你远不是第一个成为它受害者的人。

至于为什么,我只能推测,但这里有一些理由:

  • 从概念上(意思是忽略标准并从逻辑上思考语法的结构),声明是模棱两可的。声明这样的函数是完全有效的,但对象具有无arg构造函数也是完全有效的。

  • 行为应该是一致的,例如,无论此语法是被解析为函数声明还是构造函数调用,它都应该始终是其中之一,而不是另一个。

  • 如果省略括号,很明显我们实际上是在创建一个对象,并且no-arg构造函数将被自动调用。因此,对于无arg构造函数调用,存在一个明确的语法。

  • 没有一种方便的方法可以在没有括号的情况下声明函数(从技术上讲,它可以用typedefs来实现,但拜托?你真的想要一种每一个无arg函数都必须在typedef中声明其类型的语言吗?)。因此,函数声明不存在这样明确的语法。

  • 因此,将此语法视为函数声明是有意义的,因为没有其他方法可以声明函数,而有另一种方法可以创建对象。

再一次,纯粹的猜测,但对我来说是有意义的。