Возврат ссылки из-под замка: идиоматический или чертовски умный?

Предположим, у вас есть структура данных, в которой значения хранятся в узлах, например стандартные карты или списки, и эта структура имеет блокировку для ее защиты. Предположим также, что типы значений ( mapped_type для карт) достаточно сложен, чтобы у каждой был свой замок.

Итак, основная операция - захватить блокировку карты, получить (ссылку на) значение и разблокировать блокировку карты. Теперь вы можете заблокировать блокировку значения и веселиться на нем столько, сколько захотите.

Проблема - как я понимаю - в том, что вы не можете назначить ссылку - только инициализировать ее. Поэтому я предлагаю следующий вид кода, учитывая некоторый тип карты M с экземпляром m (и это мьютекс m_mutex):

      const MappedType& mt = [this, key]() -> const MappedType& {
  std::lock_guard _{m_mutex};
  return m[key];
}();

Это тот случай, когда вы можете использовать atдобавить элемент. Если вы не хотели этого делать, вы могли:

      const MappedType& mt = [this, key]() -> const MappedType& {
  std::lock_guard _{m_mutex};
  M::const_iterator it = m.find(key);
  if (m.cend() != it)
    return it->second;
  else
    return M::default_m;   // some static M to indicate 'missing', or maybe you throw
}();

Хорошая идея или слишком умен, чтобы пройти проверку кода? Каким был бы идиоматический способ сделать это в современном C++?

0 ответов

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