【发布时间】:2014-07-16 12:28:20
【问题描述】:
我发现以下延长临时人员生命周期的方案有效,我不知道是否应该,但确实如此。
struct S {
std::vector<int>&& vec;
};
int main() {
S s1{std::vector<int>(5)}; // construct with temporary
std::cout << s1.vec[0] << '\n'; // fine, temporary is alive
}
但是,当 S 被赋予显式值构造函数时,它不再是一个聚合,并且该方案因s1.vec[0] 上的无效读取而失败
struct S {
std::vector<int>&& vec;
S(std::vector<int>&& v)
: vec{std::move(v)} // bind to the temporary provided
{ }
};
int main() {
S s1{std::vector<int>(5)}; // construct with temporary
std::cout << s1.vec[0] << '\n'; // not ok. invalid read on free'd memory
}
为什么这对聚合有效?根据我使用 const lvalue refs 阅读的内容,我认为它与构造函数是一个实际的函数调用有关。另外,有什么办法可以使后一种情况起作用吗?
在 SO 上使用左值引用处理类似情况有很多问题。我看到如果我使用了 const 左值引用,它不会有助于延长临时值的生命周期,右值引用的规则是否相同?
【问题讨论】:
-
"
const lvalue refs不能延长临时对象的生命周期" - 嗯? -
这看起来像是对 C++ 的滥用(它有效并不意味着它是正确的,它可能是未定义的行为)
-
临时对象的生命周期延长规则与将临时对象绑定到引用有关,它们不区分左值和右值引用。
-
第一句话的说法有问题,提供的测试太简单了。
-
如果我没记错的话,标准中有一些有趣的条款使这种情况与其他情况不同。就像“构造函数中的引用绑定不会延长生命周期”。这里缺少构造函数意味着引用绑定是由编译器直接完成的,所以......它可能会起作用。当我考虑提出“生命周期链接”以在通过辅助函数转发临时对象时绕过一些不必要的副本时,我研究了生命周期扩展规则。
标签: c++ c++11 language-lawyer rvalue-reference object-lifetime