我有一个从中创建临时对象的类。我可以将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)
编辑:
鉴于对此可能有什么解释,是否可以进行这项工作以使分配“ const auto& v = ....”起作用?
为什么我的我不工作时,以下分配工作正常?
const auto& s = std::string("hi")[1];
std::cout << s;
Run Code Online (Sandbox Code Playgroud)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)
您的代码具有未定义的行为,很不幸,您得到了期望的结果。您正在执行与上一个示例相同的操作,并且没有获得所创建临时字符串的生命周期扩展。