copy-on-return 操作是在 lock_guard 析构函数之前还是之后执行的?

Is a copy-on-return operation executed prior or after lock_guard destructor?

get_a() 函数对于竞争条件是否安全,或者我是否需要像 get_b() 中那样显式复制 str_ 以获得线程安全函数?

class Class {
public:
  auto get_a() -> std::string {
    auto&& guard = std::lock_guard{mutex_};
    return str_;
  }
  auto get_b() -> std::string {
    auto&& guard = std::lock_guard{mutex_};
    auto str = str_;
    return str;
  }
private:
  std::mutex mutex_{};
  std::string str_{};
};

注意:我知道 Stack Overflow 上也有类似的问题,但我找不到明确回答这个问题的问题。

[stmt.return]p3:

The copy-initialization of the result of the call is sequenced before the destruction of temporaries at the end of the full-expression established by the operand of the return statement, which, in turn, is sequenced before the destruction of local variables of the block enclosing the return statement.

这意味着以下顺序发生:

  1. return 对象是复制初始化的
  2. return 语句中的任何临时对象都被销毁
  3. 局部变量被销毁

所以,我们可以推断get_a是完全安全的。