Есть ли стенография для std:: lock_guard <std:: mutex> lock (m)?
Именно то, что говорится в этом вопросе. В С++, в идеале 11, но любопытно, 14 и более поздних тоже, есть сокращенный синтаксис для:
std::mutex someMutex;
std::lock_guard<std::mutex> lg(someMutex);
В идеале что-то, что указывает на тип мьютекса, чтобы избежать рефакторинга, если я когда-либо хотел изменить на std::recursive_mutex
.
Другими словами, способ сделать это:
std::mutex someMutex;
std::lock_guard lg(someMutex);
или
auto lg = make_lock_guard(someMutex);
Для всех степеней вычитания современного С++, просто кажется ужасно избыточным, чтобы набирать std::lock_guard<std::mutex>
каждый раз, когда я хочу его создать.
Ответы
Ответ 1
Для pre-С++ 17:
template<class Mutex>
std::lock_guard<Mutex> make_lock_guard(Mutex& mutex) {
mutex.lock();
return { mutex, std::adopt_lock };
}
Использовать как:
std::mutex someMutex;
auto&& lg = make_lock_guard(someMutex);
Это использует тот факт, что инициализация списка копий не создает дополнительного временного (даже концептуально). Однопараметрический конструктор explicit
и не может использоваться для инициализации списка копий, поэтому мы сначала блокируем мьютекс, а затем используем конструктор std::adopt_lock
.
Возвращаемое значение затем напрямую привязано к lg
, которое продлевает время жизни до ссылки, снова создавая временный (даже концептуально) процесс.
Ответ 2
В дополнение к тому, что @T.C. Ответ намечен, здесь путь С++ 17:
auto lock = std::lock_guard(someMutex);
Вы можете прочитать об изменениях в этом предложении: http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2016/p0091r3.html
Ответ 3
Оба текущих ответа предполагают использование ключевого слова auto, чтобы избежать ввода имени типа. Это не так, но я предпочитаю, чтобы мой код содержал имя типа, поэтому используйте ключевое слово auto очень экономно. Я защищал бы псевдоним типа:
using MutexLockGuard = std::lock_guard<std::mutex>;