c++ - 对临时对象的 const 引用不会延长其生命周期
问题描述
我有一个类,我从中创建一个临时对象。我可以将 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;
}
编辑:
鉴于对此的解释可能是什么,是否有可能使这项工作使作业“
const auto& v = ....
”起作用?为什么以下作业有效,而我的无效?
const auto& s = std::string("hi")[1]; std::cout << s;
解决方案
const 引用仅延长函数本地临时对象的生命周期。在行
const auto& v = myval{7}.addone();
您的参考不绑定到临时。 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;
你的代码有未定义的行为,不幸的是你得到了你所期望的。您正在做与前面的示例相同的事情,并且您创建的临时字符串没有生命周期延长。
推荐阅读
- spring - 保存对象时未填充 Spring Boot JPA@CreatedDate @LastModifiedDate
- r - c() 和 | 之间的区别 在使用 R 的子集中
- javascript - 将字符串转换为对象键值
- firebase - 什么用例有 FirebaseUser 的 reload() 功能?
- java - 如何创建能够支持 @JsonFilter 注释 POJO 的全局过滤器
- laravel - Laravel Dusk:http POST 引发的 Curl 错误
- go - GoLang 将 STDOUT 和 STDERR 写入 log15 文件
- java - 如何从java中的给定日期时间字符串获取时区?
- assembly - 操作数类型不匹配 -TASM
- java - 使用泛型类型参数存储对类的引用及其实现