BGL ребро (u, v, g) с настраиваемым ассоциативным контейнером для списков ребер - PullRequest
3 голосов
/ 07 февраля 2012

Я только начал изучать bgl и столкнулся с проблемой при использовании std :: set с пользовательским порядком в качестве контейнера для списков ребер в adjacency_list.Я определяю оператор <, чтобы упорядочить ребра, основываясь на их свойствах, так же, как в примере order_out_edges.cpp.Здесь boost :: edge_unique_ordering - это тег пользовательского свойства. </p>

template < typename Edge >
struct order_by_unique_order: public std::binary_function< Edge, Edge, bool >
{
    inline bool operator() (const Edge& e1, const Edge& e2) const
    {
        return boost::get(boost::edge_unique_ordering, e1) < boost::get(boost::edge_unique_ordering, e2);
    }
};

struct default_edge_containerS {};

namespace boost
{
    template < class ValueType >
    struct container_gen< default_edge_containerS, ValueType >
    {
        typedef std::set< ValueType, order_by_unique_order< ValueType > > type;
    };
}

В целом, он работает нормально, но я получаю исключения итератора, когда использую функцию edge (u, v, g).Если я заменю эти вызовы обходным путем, чтобы не запрашивать ребра с помощью (источник, цель), то все будет хорошо.

Я просмотрел код повышения и вполне уверен, что знаю причину, я 'Я просто не уверен, означает ли это, что я делаю что-то не так, это проблема с буст-кодом или просто недокументированная несовместимость.Функция вызывает set :: find (StoredEdge (v)) для контейнера списка внешних ребер u.Теперь по умолчанию сохраненный_оператор :: оператор <просто сравнивает целевые вершины, но в моем случае вызывается мой пользовательский оператор <, и искомый StoredEdge (v) явно инициализируется по умолчанию без свойств, что, вероятно, является причинойэта проблема.Мне кажется, что ребро (u, v, g) должно искать любое совпадение, основанное строго на целевой вершине, независимо от того, какой порядок наложен на ребра внутри контейнера. </p>

Может ли кто-нибудь пролить светна что я могу поступать неправильно или не понимать?

1 Ответ

1 голос
/ 13 февраля 2012

Похоже, вам нужно написать оператор сравнения оболочки, который принимает тип (который будет заполнен с использованием типа StoredEdge) и сравнивает результаты get_target) на двух входах, используя вашу пользовательскую функцию сравнения, используя что-то вроде:

template <typename Cmp>
struct target_compare {
  Cmp cmp;
  target_compare(const Cmp& cmp): cmp(cmp) {}
  template <typename SE>
  bool operator()(const SE& a, const SE& b) const {
    return cmp(a.get_target(), b.get_target());
  }
};

затем используйте target_compare<order_by_unique_order<Edge> > в качестве типа сравнения в вашем set.

...