- mongodb - 在 MongoDB mapreduce 中,如何展平值对象?
- javascript - 对象传播与 Object.assign
- html - 输入类型 ="submit"Vs 按钮标签它们可以互换吗?
- sql - 使用 MongoDB 而不是 MS SQL Server 的优缺点
我是 C++ 初学者,想了解原因
return std::list<int>();
需要括号,但是
std::list<int> foo;
不需要括号。这些构造函数调用有什么区别?
最佳答案
这些都不是构造函数调用。
第一个是 explicit type conversion ,它创建一个类型为 std::list<int>
的对象.
第二个是变量定义,它创建了一个 std::list<int>
类型的对象。 .
默认构造函数(不带参数的构造函数)在这两种情况下都作为创建的一部分被调用。
尽管您可能会看到诸如“构造函数调用”之类的东西,但在 C++ 中没有显式和单独调用构造函数的语法构造。
一个需要括号而另一个不需要括号的原因是因为它们是两种不同的语言结构,具有不同的语法,而不是两种调用构造函数的方式。
请注意,如果您在第二个示例中添加括号,您实际上是在声明一个函数,而不是定义一个变量:
std::list<int> foo; //variable definition
std::list<int> foo(); //function taking no args, returning a std::list<int>
这通常称为 most-vexing-parse . C++11 引入了支撑初始化来解决这个问题:
std::list<int> foo{}; //variable definition
(引自 N3337)
“但是 T()
看起来确实像构造函数调用,为什么不是?”
在这种情况下,T()
被称为具有函数符号的显式类型转换:
5.2.3 Explicit type conversion (functional notation) [expr.type.conv]
1 [...]
2 The expression
T()
, whereT
is a simple-type-specifier or typename-specifier for a non-array complete object type or the (possibly cv-qualified) void type, creates a prvalue of the specified type, which is value-initialized (8.5; no initialization is done for the void() case). [Note: ifT
is a non-class type that is cv-qualified, the cv-qualifiers are ignored when determining the type of the resulting prvalue (3.10). —end note ]
所以这会创建一个 prvalue,它是 value-initialized。
[dcl.init]/7:
To value-initialize an object of typeT
means:— if T is a (possibly cv-qualified) class type (Clause 9) with a user-provided constructor (12.1), then the default constructor for T is called (and the initialization is ill-formed if T has no accessible default constructor);
— [...]
所以这调用构造函数作为值初始化的一部分,这是显式类型转换的一部分。如上所述,没有办法直接调用构造函数。标准说:
[class.ctor]/1:
Constructors do not have names. A special declarator syntax is used to declare or define the constructor. The syntax uses:— an optional decl-specifier-seq in which each decl-specifier is either a function-specifier or constexpr,
— the constructor’s class name, and
— a parameter list
in that order. In such a declaration, optional parentheses around the constructor class name are ignored.
因此构造函数没有名称,我们使用语言定义的语法异常来声明/定义它们。
“这似乎是学术上的区别,这在实践中重要吗?”
也许,也许不是。我的观点是,将上述语法解释为纯构造函数调用描绘了构造函数是什么的错误画面。构造函数初始化一个对象;它不分配该对象的内存、返回初始化的对象、将符号绑定(bind)到该对象或通过变量定义和类型转换完成的任何其他事情。此外,它可能会像 OP 那样造成困惑,因为他认为这两个构造都是构造函数调用,所以他希望使用统一的语法。
当我们有避免混淆的正式术语时,为什么要使用不精确的提喻?
关于c++ - 带和不带 ( ) 的构造函数调用之间的区别,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33079486/
平时很少在jquery中用到this。查看代码时发现用到了,就调试出this的值,心想原来如此。还是挺有用的。这里总结一下this与$(this)的区别和使用。 $(this)生成的是什么?
使用单例类和应用程序范围的托管 bean 来保存应用程序数据有区别吗? 我需要查找某些 JNDI 资源,例如远程 bean 接口(interface),因此我为自己编写了一个单例来缓存我的引用并且只允
如果您仔细查看包含的图片,您会注意到您可以使用 Eclipse IDE 重构 Groovy 代码并将方法转换为闭包,反之亦然。那么,闭包到底是什么,它与方法有什么不同呢?有人可以举一个使用闭包的好例子
vagrant box repackage有什么区别( docs ) 和 vagrant package ( docs )? 我意识到 vagrant package仅适用于 VirtualBox 提
我想看看是否有人可以解释为什么以下代码适用于 valueOf 但不适用于其他代码。 import java.math.BigDecimal; public class Change { publ
这个问题已经有答案了: 已关闭12 年前。 Possible Duplicates: What is Closures/Lambda in PHP or Javascript in layman te
This question already has answers here: Vagrant, Docker, Puppet, Chef (3个答案) 2年前关闭。 docker和chef有什么共同
以下代码在95%的机器上产生相同的输出,但是在几台机器上却有所不同。在 Debug模式下,输出: Changing from New to Fin OK 但在 Release模式下: Changing
////Creating Object var Obj; // init Object Obj= {}; 它们之间有什么区别两个? 有没有可能把它变成一个单行? 这样使用有什么好处吗?
我想找出定时器服务之间的区别。我应该使用哪个以及何时使用。我正在使用 Jboss 应用服务器。 1) java.ejb.Schedule。 @Schedule注解或配置自xml。 2) javax.e
我发现在 C++ 中可以通过三种不同的方式将对象传递给函数。假设我的类(class)是这样的: class Test { int i; public: Test(int x);
有什么区别。 public class Test { public static void main(String args[]) { String toBeCast = "c
如果我有一列,设置为主索引,设置为INT。 如果我不将其设置为自动递增,而只是将唯一的随机整数插入其中,与自动递增相比,这是否会减慢 future 的查询速度? 如果我在主索引和唯一索引为 INT 的
这两种日期格式有什么区别。第一个给出实际时间,第二个给出时间购买添加时区偏移值。 NSDateFormatter * dateFormatter = [[NSDateFormatter alloc]
如果有一个函数,请说foo: function foo() { console.log('bar'); } 那么在 JavaScript 中,从另一个函数调用一个函数有什么区别,如下所示: f
关闭。这个问题是opinion-based 。目前不接受答案。 想要改进这个问题吗?更新问题,以便 editing this post 可以用事实和引文来回答它。 . 已关闭 4 年前。 Improv
代码是什么: class Time { private: int hours; int minutes; int seconds; pu
我知道这是非常基本的,但有人介意解释一下这两个数组声明之间的区别吗: #include array myints; ...和: int myints[5]; ...以及为什么 myints.size
我学会了如何根据 http://reference.sitepoint.com/css/specificity 计算 css 特异性但是,基于this reference,我不明白伪类(来自c)和伪元
为什么在运行 2) 时会出现额外的空行?对我来说 1 就像 2。那么为什么 2) 中的额外行? 1) export p1=$(cd $(dirname $0) && pwd) #
我是一名优秀的程序员,十分优秀!