我想知道 prvalue
是否与 C++17 中的 temporary
相同。考虑以下示例,
//C++17 example
#include <iostream>
struct Custom
{
Custom()
{
std::cout<<"default constructor called"<<std::endl;
}
Custom(const Custom& var)
{
std::cout<<"copy constructor called"<<std::endl;
}
~Custom()
{
std::cout<<"destructor called"<<std::endl;
}
};
Custom func()
{
Custom temp;
return temp;//this will use copy constructor
}
int main() {
func();
}
假设上面的代码是在启用-fno-elide-constructors
选项的情况下执行的,我的问题是作为名为temp的本地对象的拷贝创建的纯右值是否函数
与 C++17 中的临时代码相同。func
中的
我读到在 C++17 中,纯右值不是对象。例如,here用户说
"Prvalues are not objects (since C++17)".
同样,here用户说
"Before C++17 the prvalue was already the temporary, which is what your quote refers to. Since C++17 the prvalue itself is not a temporary..."
但这让我感到困惑,因为如果纯右值不是对象,那它又是什么?我的意思是,在上面的示例中,temp
的拷贝是使用复制构造函数创建的。现在,在 C++17 之前,该拷贝是一个 临时对象,它是一个纯右值。但是 C++17 中发生了什么变化。我的想法是,我们仍然有一个使用复制构造函数创建的纯右值,并且该纯右值在 C++17 中是一个临时值,因为它存在的时间有限。
PS:我在描述实际发生的事情时可能是错误的,所以请通过解释 C++17 中发生的事情以及它与 C++14 的不同之处来纠正我。我也在问,因为我已经阅读了 SO 帖子(类似的帖子),在上面的示例中,C++17 中没有临时涉及,我不明白这是怎么可能的。
最佳答案
But that confused me because if an prvalue is not an object, then what is it?
可以成为对象的表达式。
My thinking is that we still have an prvalue that is created using the copy constructor and that prvalue is a temporary in C++17 because it exists for some limited duration.
纯右值还不是对象(或者这里有不同的想法)。
让我们通过使用 func
初始化一些东西来扩展您的示例。
int main() {
auto obj = func();
}
main
中的obj
和func
中的temp
是“同一个对象”。这就像如果 func
被代替
void func(Custom * result) {
Custom & temp = *new(result) Custom;
}
int main() {
char storage[sizeof(Custom)];
Custom & obj = *reinterpret_cast<Custom *>(storage);
func(&obj);
obj.~Custom();
}
或者使用 -fno-elide-constructors
将 temp
的拷贝留在返回值中:
void func(Custom * result) {
Custom temp;
new(result) Custom(temp);
}
C++14 到 C++17 之间的变化不是抽象机行为的允许差异,而是抽象机的定义被更改为具有该行为。
关于c++ - 纯右值与 C++17 中的临时值相同吗,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/71556308/