Выполняется ли операция копирования при возврате до или после деструктора lock_guard?

Это get_a() функция безопасна для условий гонки или мне нужно явно скопировать str_ как в get_b() для того, чтобы иметь потокобезопасную функцию?

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_{};
};

Примечание: я знаю, что здесь есть похожие вопросы о переполнении стека, но я не смог найти тот, который явно отвечает на этот вопрос.

1 ответ

Решение

[stmt.return] p3:

Инициализация копии вызова вызывается последовательно до уничтожения временных значений в конце полного выражения, установленного операндом return оператор, который, в свою очередь, упорядочен до уничтожения локальных переменных блока, содержащего return заявление.

Это означает, что происходит следующее:

  1. Возвращаемый объект инициализируется копией
  2. Все временные файлы внутри оператора return уничтожаются
  3. Локальные переменные уничтожены

Итак, мы можем сделать вывод, что get_a совершенно безопасно.

Другие вопросы по тегам