LINUX.ORG.RU

История изменений

Исправление eao197, (текущая версия) :

Может быть вы напишете более простой пример?

Да тут важен принцип: MultiIndex — это контейнер, в котором доступ к объекту можно получать по разным ключам. Для совсем простого примера можно взять объект:

struct A {
  std::string a_;
  std::string b_;
};
И попробовать написать контейнер multi_index_A:
class multi_index_A {
public :
  void emplace(std::string a, std::string b);
  const A * find_by_a(const std::string & key) const;
  const A * find_by_b(const std::string & key) const;
  void erase_by_a(const std::string & key);
  template< typename It > void erase_by_a(It begin, It end);
  void erase_by_b(const std::string & key);
  template< typename It > void erase_by_b(It begin, It end);
};
В простом случае такой multi_index_A реализуется через два std::map-а:
class multi_index_A {
  using A_shptr = std::shared_ptr<A>;
  std::map<std::string, A_shptr> index_a_;
  std::map<std::string, A_shptr> index_b_;
public :
  ...
};
А методы erase_by_a и erase_by_b вынуждены удалять объект сначала из одного контейнера, затем из другого.

Написание таких методов для случая, когда исключения из деструкторов не летят не представляет особой проблемы.

Попробуйте сделать то же самое для случая с исключениями из деструкторов. И чтобы хоть какие-то гарантии exception safety обеспечивались.

Исходная версия eao197, :

Может быть вы напишете более простой пример?

Да тут важен принцип: MultiIndex — это контейнер, в котором доступ к объекту можно получать по разным ключам. Для совсем простого примера можно взять объект:

struct A {
  std::string a_;
  std::string b_;
};
И попробовать написать контейнер multi_index_A:
class multi_index_A {
public :
  void emplace(std::string a, std::string b);
  const A * find_by_a(const std::string & key) const;
  const B * find_by_b(const std::string & key) const;
  void erase_by_a(const std::string & key);
  template< typename It > void erase_by_a(It begin, It end);
  void erase_by_b(const std::string & key);
  template< typename It > void erase_by_b(It begin, It end);
};
В простом случае такой multi_index_A реализуется через два std::map-а:
class multi_index_A {
  using A_shptr = std::shared_ptr<A>;
  std::map<std::string, A_shptr> index_a_;
  std::map<std::string, A_shptr> index_b_;
public :
  ...
};
А методы erase_by_a и erase_by_b вынуждены удалять объект сначала из одного контейнера, затем из другого.

Написание таких методов для случая, когда исключения из деструкторов не летят не представляет особой проблемы.

Попробуйте сделать то же самое для случая с исключениями из деструкторов. И чтобы хоть какие-то гарантии exception safety обеспечивались.