对临时对象的Const引用不会延长其生存期
Const reference to temporary object does not extend its lifetime
我有一个类,从中创建一个临时对象。我可以将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 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;
你的代码有未定义的行为,不幸的是你得到了你想要的。您正在执行与上一个示例相同的操作,并且您创建的临时字符串没有得到生存期扩展。
引用寿命扩展仅在直接应用于前额临时对象时有效。
应用于引用时没有引用生存期扩展。
myval&& addone() && {
i[0]++;
return std::move(*this);
}
返回一个引用。(右值和左值引用都是引用的类型(
const auto& v = myval{7}.addone();
这不会延长引用的生存期,因为我们将const auto& v
绑定到引用,而不是临时的。
我们如何让它发挥作用?重写addone
的签名,我们得到:
myval addone() && {
i[0]++;
return std::move(*this);
}
现在它返回一个prvalue而不是引用。
const auto& v = myval{7}.addone();
现在这个引用寿命延长了。
你的"为什么这样有效"后续是因为未定义的行为可以做任何事情,包括"看起来有效"。它不是有效的代码。
相关文章:
- 在不复制临时对象的情况下延长其生存期
- 结束另一个线程中使用的对象的生存期
- "this"指针的值在对象的生存期内是否恒定?
- C++17 和静态临时生存期的参考扩展
- 数组对象的生存期是否在重用其元素存储时结束?
- 具有空洞初始化的对象的生存期
- 如何在向量列表初始化时避免对象复制以及如何延长临时的生存期
- 子表达式中临时对象的生存期
- 对临时对象的Const引用不会延长其生存期
- 对象存在与对象生存期不同吗
- 有什么方法可以延长C++中临时对象的生存期吗
- 在函数调用中C++临时对象的生存期
- 为什么常量引用不能延长通过函数传递的临时对象的生存期?
- C++临时对象成员函数的生存期
- 范围内临时对象的生存期是多少?
- 传递给存储常量引用的成员的临时对象的生存期
- 三元运算符和通过引用const延长临时对象的生存期
- 对临时对象的常量引用在函数作用域(生存期)后被破坏
- 为什么临时的生存期不会延长到封闭对象的生存期?
- 防止创建具有静态生存期的对象