c++ - 对临时对象的常量引用不会延长其生命周期

标签 c++ c++14 c++17

我有一个类,我从中创建了一个临时对象。我可以将一个 const-reference 绑定(bind)到这个临时对象,它按预期工作。但是,如果我在这个临时对象上调用一个返回 std::move(*this) 的成员函数,并绑定(bind)到这个返回值,它就不会像我预期的那样工作。下面的简短代码重现了我的问题并且不言自明。

#include <iostream>
#include <cstdlib>
#include <vector>

class myval {
    public:
    std::vector<int> i;
    myval(int i) : i({i}) {}
    myval(const myval& v) = delete;
    myval(myval&& v) : i(std::move(v.i)) {}
    myval&& addone() && {
        i[0]++;
        return std::move(*this);
    }

};

int main()
{
    //Object is moved, works like expected
    const auto moved_value = myval{7}.addone();
    std::cout << moved_value.i[0] << std::endl;

    //Const reference is supposed extend the lifetime of a temporary object
    const auto& u = myval{7};
    //Prints 7, as expected
    std::cout << u.i[0] << std::endl;

    const auto& v = myval{7}.addone();
    //Why does this print 0?
    std::cout << v.i[0] << std::endl;

    return 0;
}

编辑:

  1. 鉴于对此的解释可能是什么,是否有可能使这项工作有效,以便分配“const auto& v = ....”有效?

  2. 为什么下面的作业有效而我的却没有?

    const auto& s = std::string("hi")[1];
    std::cout << s;
    

最佳答案

const 引用只会延长函数本地临时对象的生命周期。在行中

const auto& v = myval{7}.addone();

您的引用未绑定(bind)到临时文件。 addone 通过引用返回,这意味着您使用的是左值而不是临时值,因此当完整表达式结束时,您留下的是对不再存在的对象的引用。


关于编辑。制作

const auto& v = myval{7}.addone();

我会将 addone 更改为按值返回

myval addone() && {
    i[0]++;
    return std::move(*this);
}

然后这将为您提供正确的行为,因为它将对象移动到临时对象中,然后您可以延长其生命周期。

为了

const auto& s = std::string("hi")[1];
std::cout << s;

您的代码有未定义的行为,不幸的是您得到了您期望的结果。您正在做与前面示例相同的事情,并且您创建的临时字符串的生命周期没有延长。

关于c++ - 对临时对象的常量引用不会延长其生命周期,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58697397/

相关文章:

c++ - 判断一个抽象基类的构造函数是否为noexcept?

c++ - Qt toDouble() 方法转换为 int

ZeroMemory 的 C# 等效代码

使用 future 、 promise 、分离线程时出现 C++ 错误 C2893、C2780、C2672

c++ - 如何检查 union 是否包含类型(使用 type_traits)?

c++ - 如何使用 type_traits 仅在特定类型上添加模板类的成员函数 | C++

c++ - 两个 for 循环和其中的一个 if 语句

c++ - 在全局范围内重载 std 容器上的运算符是一种不好的风格吗?

c++ - "No match for operator-"简单迭代器差异错误

c++ - 将折叠表达式传递给可变参数模板