gpt4 book ai didi

c++ - 通过右值引用返回与通过值返回

转载 作者:塔克拉玛干 更新时间:2023-11-03 00:27:56 26 4
gpt4 key购买 nike

大多数 C++ 标准库实用程序在为此重载右值限定符时通过右值引用返回。例如 std::optional 对 value() 函数有以下重载

constexpr T& value() &;
constexpr const T & value() const &;
constexpr T&& value() &&;
constexpr const T&& value() const &&;

这允许在需要时移动返回值,很好。这是一个可靠的优化。

但是与返回右值相关的不确定性呢?例如(这里是活生生的例子 https://wandbox.org/permlink/kUqjfOWWRP6N57eS )

auto get_vector() {
auto vector = std::vector<int>{1, 2, 3};
return std::optional{std::move(vector)};
}

int main() {
for (auto ele : *get_vector()) {
cout << ele << endl;
}
}

上面的代码导致了未定义的行为,因为基于 for 循环的范围是如何扩展的

{
auto && __range = range_expression ;
auto __begin = begin_expr ;
auto __end = end_expr ;
for ( ; __begin != __end; ++__begin) {
range_declaration = *__begin;
loop_statement
}
}

当绑定(bind)到 *get_vector() 的返回值时转发引用 range 不会延长 xvalue 的生命周期。并导致绑定(bind)到一个被破坏的值。因此导致 UB。

为什么不按值返回并在内部移动存储的对象?特别是因为现在 C++17 有 prvalue 优化,例如

auto lck = std::lock_guard{mtx};

请注意,这与此处的问题不同 C++11 rvalues and move semantics confusion (return statement) ,这没有提到右值返回容器/持有者的生命周期延长问题,并且在 C++17 对 prvalues 强制省略之前被问到

最佳答案

Why not return by value and internally move the stored object?

因为这可能比返回引用效率低。考虑这样一种情况,您使用返回的引用从该对象中获取另一个引用。例如 (*get_vector())[3]。对于您提议的更改,这是对原件拷贝的引用;按照目前的方式,它是对原始临时值中的值的引用。

C++ 作为一种语言并不能有效地处理对临时对象的引用的生命周期。目前的解决方案包括要么注意生命周期,要么不使用引用并使用可能较慢/效率较低的代码。一般来说,标准库更愿意在性能方面犯错误。

关于c++ - 通过右值引用返回与通过值返回,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46392420/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com