const对临时对象的引用不会延长其寿命

DDa*_*iel 0 c++ c++14 c++17

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

#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;
}
Run Code Online (Sandbox Code Playgroud)

编辑:

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

  2. 为什么我的我不工作时,以下分配工作正常?

    const auto& s = std::string("hi")[1];
    std::cout << s;
    
    Run Code Online (Sandbox Code Playgroud)

Nat*_*ica 5

const引用只会延长函数局部临时变量的生存期。在行中

const auto& v = myval{7}.addone();
Run Code Online (Sandbox Code Playgroud)

您的参考资料不限于临时资料。 addone通过引用返回,这意味着您正在使用左值而不是临时值,因此,当完整表达式结束时,您将获得对不再存在的对象的引用。


关于编辑。为了

const auto& v = myval{7}.addone();
Run Code Online (Sandbox Code Playgroud)

我会改变addone按价值返回

myval addone() && {
    i[0]++;
    return std::move(*this);
}
Run Code Online (Sandbox Code Playgroud)

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

对于

const auto& s = std::string("hi")[1];
std::cout << s;
Run Code Online (Sandbox Code Playgroud)

您的代码具有未定义的行为,很不幸,您得到了期望的结果。您正在执行与上一个示例相同的操作,并且没有获得所创建临时字符串的生命周期扩展。