MyClass 对象 = MyClass(); 'MyClass()' 在这里指的是一个临时对象吗?
MyClass obj = MyClass(); Does 'MyClass()' refer to a temporary object here?
考虑不涉及复制省略的情况(C++17 之前)。
来自 cppreference(再次假设 C++14):
Temporary objects are created in the following situations:
- binding a reference to a prvalue
- returning a prvalue from a function
- conversion that creates a prvalue
- lambda expression
- copy-initialization that requires conversion of the initializer
- list-initialization that constructs an std::initializer_list
- reference-initialization to a different but convertible type or to a bitfield.
除了第一个之外的所有情况似乎都不相关,第一个似乎意味着 C++ 样式的引用绑定(int &&x = 5;
顺便说一句,在这种情况下我不明白临时对象最后被销毁的说法完整表达式...,对象 5 所指的似乎在语句末尾没有被破坏)。
因此,据我了解,临时对象的概念仅包括那些保证被存储的对象(由于可能省略,在我的情况下不是这种情况)。我对么?否则我在这里误解了什么?
顺便说一句,MyClass()
和 int x = 4;
中的 4
(或 int x = 2 + 2;
中的 2 + 2
)有什么区别吗?就像我可能不正确,第一个确实引用了一个临时对象,而其他两个则没有...
C++14 标准[1] 在 12.2 中关于临时对象 ([class.temporary]) 的规定:
Temporaries of class type are created in various contexts: binding a reference to a prvalue ([...]), returning
a prvalue ([...]), a conversion that creates a prvalue ([...], 5.4), throwing an exception ([...]),
and in some initializations ([...]).
在MyClass obj = MyClass();
中,MyClass()
是函数符号中的显式类型转换,所以它是一个临时对象,因为它属于"conversion that creates a prvalue"。
这不适用于 int x = 4;
中的 4
,因为规则引用 "class types",但 int
是 "fundamental type"。
另外 8.5 Initializers ([dcl.init]) 将子句 (17.8) 中非 class 类型初始化器的语义定义为
Otherwise, the initial value of the object being initialized is the (possibly converted) value of the initializer
expression. [...]
而对于 class 类型,将调用(复制)构造函数。所以你需要一个(临时)对象来复制 class 类型,而不是 "other" 类型。
[1]:实际上 N4296,但这应该没什么区别
是的,它创建了一个临时值,因为这是一个显式转换,创建了一个纯右值。
在此上下文 MyClass obj = MyClass();
中,MyClass()
是 prvalue。从您提供的引文来看,它符合情况 "创建纯右值的转换",所以是的,创建了一个临时文件。
实际上,编译器会将此行 MyClass obj = MyClass();
转换为:(假设 MyClass 具有 non-deleted 个默认和复制构造函数)
MyClass _tmp{}; // (default-constructed)
MyClass obj = _tmp; // (copy-constructed)
第一行调用:MyClass::MyClass(this=&_tmp)
第二行调用:MyClass::MyClass(MyClass const&=tmp, this=&obj)
考虑不涉及复制省略的情况(C++17 之前)。
来自 cppreference(再次假设 C++14):
Temporary objects are created in the following situations:
- binding a reference to a prvalue
- returning a prvalue from a function
- conversion that creates a prvalue
- lambda expression
- copy-initialization that requires conversion of the initializer
- list-initialization that constructs an std::initializer_list
- reference-initialization to a different but convertible type or to a bitfield.
除了第一个之外的所有情况似乎都不相关,第一个似乎意味着 C++ 样式的引用绑定(int &&x = 5;
顺便说一句,在这种情况下我不明白临时对象最后被销毁的说法完整表达式...,对象 5 所指的似乎在语句末尾没有被破坏)。
因此,据我了解,临时对象的概念仅包括那些保证被存储的对象(由于可能省略,在我的情况下不是这种情况)。我对么?否则我在这里误解了什么?
顺便说一句,MyClass()
和 int x = 4;
中的 4
(或 int x = 2 + 2;
中的 2 + 2
)有什么区别吗?就像我可能不正确,第一个确实引用了一个临时对象,而其他两个则没有...
C++14 标准[1] 在 12.2 中关于临时对象 ([class.temporary]) 的规定:
Temporaries of class type are created in various contexts: binding a reference to a prvalue ([...]), returning a prvalue ([...]), a conversion that creates a prvalue ([...], 5.4), throwing an exception ([...]), and in some initializations ([...]).
在MyClass obj = MyClass();
中,MyClass()
是函数符号中的显式类型转换,所以它是一个临时对象,因为它属于"conversion that creates a prvalue"。
这不适用于 int x = 4;
中的 4
,因为规则引用 "class types",但 int
是 "fundamental type"。
另外 8.5 Initializers ([dcl.init]) 将子句 (17.8) 中非 class 类型初始化器的语义定义为
Otherwise, the initial value of the object being initialized is the (possibly converted) value of the initializer expression. [...]
而对于 class 类型,将调用(复制)构造函数。所以你需要一个(临时)对象来复制 class 类型,而不是 "other" 类型。
[1]:实际上 N4296,但这应该没什么区别
是的,它创建了一个临时值,因为这是一个显式转换,创建了一个纯右值。
在此上下文 MyClass obj = MyClass();
中,MyClass()
是 prvalue。从您提供的引文来看,它符合情况 "创建纯右值的转换",所以是的,创建了一个临时文件。
实际上,编译器会将此行 MyClass obj = MyClass();
转换为:(假设 MyClass 具有 non-deleted 个默认和复制构造函数)
MyClass _tmp{}; // (default-constructed)
MyClass obj = _tmp; // (copy-constructed)
第一行调用:MyClass::MyClass(this=&_tmp)
第二行调用:MyClass::MyClass(MyClass const&=tmp, this=&obj)