如何使rValue引用在RR获取其值的try块之外可用

How to make a rValue reference available outside the try-block in which the RR obtains its value?

本文关键字:try rValue 何使 引用 获取 RR      更新时间:2023-10-16

假设我们不想重新设计函数a_func_that_may_throw

try {
    T&& rr = a_func_that_may_throw();
}
catch (const std::exception& e) {
    /* Deal with the exception here. */
}
// Question: How to adapt the code above so as to have `rr` available here?

很抱歉没有问清楚我的问题。添加以下内容是为了(希望)使问题更清楚。

我们可以这样做的指针:

T *ptr = nullptr;
try {
    ptr = a_source_that_may_throw();
}
catch (const std::exception& e) {
    /* We know what happened in the try block and can do something without `ptr`. */
}
// `ptr` is available out side the try block.

从C++11开始,我们的工具架上就有了rValue引用,这使我们免于低效地复制现有(可能设计不好)函数返回的巨大对象。是否可以同时享受这两种优势,这样我们就不必复制,并且仍然可以像上面代码中使用ptr一样访问返回的对象?

谢谢。m(__)m

如果使用r值引用的原因是希望将非常量引用绑定到临时引用,那么IMHO就不用麻烦了。相反,使用值语义并让编译器进行优化。

T t;
try {
    t = a_func_that_may_throw(); // Compiler can use RVO and move assign to 't'.
} catch (const std::exception& e) {
    /* Deal with the exception here. */
}
// 't' has lifetime until end of scope.

如果T不是默认可构造的或可移动可赋值的,则会出现异常。

或者,按照@Kerrek SB在评论中提到的方式进行,即将所有内容移动到try块中。

这取决于您所说的"处理异常"是什么意思。你可以这样做:

T wrap_a_func_that_may_throw() {
  try {
    return a_func_that_may_throw();
  } catch(const std::exception& e) {
    // Do cleanup, logging, etc...
    // May have to re-throw if there is
    // nothing meaningful you can return.... 
  }
  return T()  // Return empty T if possible.
}
Foo&& foo = wrap_a_func_that_may_throw();

这让您有机会进行任何特定的清理、日志记录等,但可能需要重新抛出。正如Kerrek SB所说,您可能仍然需要在try块中拥有使用引用的所有内容。