Вопрос

Я хотел бы иметь две структуры, которые указывают друг на друга.В частности, мне хотелось бы иметь следующее:

template<typename Key, typename Value> 
class MyStructure {
public:
  typedef map<Key, list<pair<Value, typename ListType::iterator>>> MapType;
  typedef list<typename MapType::element_type::iterator> ListType;
private:
  MapType map_;
  ListType list_;
}

Очевидно, это не сработает, поскольку ListType ранее не был объявлен как тип.Как я мог это сделать?Как видите, я использую типы итераторов как указатели на элементы этих двух структур.

Я подумывал использовать любопытный повторяющийся шаблон шаблона, но ничего с этим не добился.Кто-то из ##c++ также предложил использовать псевдонимы шаблонов, но это тоже не удалось (по крайней мере, я не знаю, как использовать эту идею).

Я делаю что-то не так концептуально?Или, возможно, «не соответствует концепциям C++»?Я, конечно, мог бы сделать это с помощью void*s, но я пытаюсь сделать все правильно :)

Спасибо!

Это было полезно?

Решение

Хотя я подозревал, что это может быть дубликат (и во многих отношениях), «ура и ед. - Альф» - это правильно, указывая, что потенциальный дубликат вопрос был конкретно об использовании typedef для такого рода вещей,

Однако в настоящем вопросе ОП хотел бы знать, как вообще справиться с взаимным включением в сценарии, описанном в вопросе.

Вот предложение:

#include <list>
#include <map>

template <typename Key, typename Value>
class MyElement;

template <typename Key, typename Value>
class MyStructure
{
public:
  typedef std::map<Key,MyElement<Key,Value> > MapType;
  typedef std::list<MyElement<Key,Value> >    ListType;
};

template <typename Key, typename Value>
class MyElement {
public:
  typename MyStructure<Key,Value>::MapType::iterator  map_iterator;
  typename MyStructure<Key,Value>::ListType::iterator list_iterator;
};
.

Как вы можете видеть, я представил новый тип данных MyElement, который содержит итератор списка, а также итератор карты.Потому что это класс, а не Typedef, это может быть объявлено вперед.

Другие советы

К сожалению, это невозможно в том смысле, в котором вы это выражаете.

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

Что, если бы вы использовали list принадлежащий Values, а потом карта указывала на этот список?

Это сломало бы циклическую зависимость.

typedef std::list< std::pair<Key, Value> > ListType;
typedef std::multiset<typename ListType::iterator, CmpFirst> MapType;

(Не уверен, что я действительно понял, чего вы пытались достичь...)

Другое решение, которое вам, вероятно, следует рассмотреть, — это посмотреть, можете ли вы выразить это в терминах Boost.MultiIndex.Когда необходимо несколько итераций/шаблонов поиска, Boost.MultiIndex часто является лучшей альтернативой, чем решение, созданное вручную, поскольку оно чередует индексы внутри значений, чтобы минимизировать объем памяти.Плюс согласованность (т. е. наличие всех индексов, ссылающихся на один и тот же набор элементов) является само собой разумеющимся.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top