声明"vector<int> myvector()"做什么?(关于无参数构造函数的混淆)
What does the statement "vector<int> myvector()" do? (confusion regarding parameterless constructor)
我希望有人能澄清我对尝试使用无参数构造函数的语法的困惑。现在,我认为正确的语法要么没有括号:
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构造函数调用,存在一个明确的语法。
没有一种方便的方法可以在没有括号的情况下声明函数(从技术上讲,它可以用
typedef
s来实现,但拜托?你真的想要一种每一个无arg函数都必须在typedef
中声明其类型的语言吗?)。因此,函数声明不存在这样明确的语法。因此,将此语法视为函数声明是有意义的,因为没有其他方法可以声明函数,而有另一种方法可以创建对象。
再一次,纯粹的猜测,但对我来说是有意义的。
- 如何将C++闭包与变量参数同时重用——类似于JavaScript
- 使用模板参数重载C++方法:如何使其适用于模板的子类?
- 无法让"std::enable_if"适用于无作用域枚举
- atoi() 在应用于大型命令行参数时会产生不正确的值
- Constexpr 可变参数模板,用于对无符号整数进行重新排序
- 指向(数据)成员的指针作为非类型模板参数,例如具有自动存储持续时间/无链接
- 应用于无符号类型的一元减号运算符
- C++函数,它将数组、谓词和运算符作为参数,并将运算符应用于满足谓词的数组元素
- C++带有适用于左值和右值的引用参数的函数
- 类成员函数参数列表是否可以依赖于模板参数?
- 适用于大型数组的无复制线程安全环形缓冲区
- 专用于可变参数模板成员函数
- 通过参数传递 lambda(无函数类型模板)
- C 从函数指针推导的转发参数时无隐式转换
- 错误 一元减号运算符应用于无符号类型会导致无符号
- MSVS 2015 显式错误 C4146 - 应用于无符号类型的一元减号运算符
- 错误 C4146:一元减号运算符应用于无符号类型,结果仍然无符号
- 作为参数的无名称空指针
- 如何使C++函数使用双精度参数或无参数执行
- XGCC标准参数h无此类文件或目录