c++ - 纯右值与 C++17 中的临时值相同吗

标签 c++ c++17 language-lawyer rvalue temporary

我想知道 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 选项的情况下执行的,我的问题是作为名为tempfunc 中的 与 C++17 中的临时代码相同。

我读到在 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 中的

objfunc 中的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-constructorstemp 的拷贝留在返回值中:

void func(Custom * result) {
    Custom temp;
    new(result) Custom(temp);
}

C++14 到 C++17 之间的变化不是抽象机行为的允许差异,而是抽象机的定义被更改为具有该行为。

关于c++ - 纯右值与 C++17 中的临时值相同吗,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/71556308/

相关文章:

c++ - C++ 中的运算符 |= 及其用法

c++ - 成员变量在另一个线程中没有改变?

c++ - 断言中的折叠表达式在某些机器上编译,但在其他机器上不编译

c++ - 在 NULL 指针上调用 delete - C++03 与 C++11

c++ - std::min(0.0, 1.0) 和 std::max(0.0, 1.0) 会产生未定义的行为吗?

c++ - 构造函数干扰成员变量指定初始化器?

c++ - 意外的引用行为

c++ - 调用 `string::c_str()` 时实际上做了什么?

c++ - 如何使用 std::forward 评估参数包的扩展?

c++ - 局部常量变量不是 constexpr 可评估的,但无法弄清楚为什么