BGL ребро (u, v, g) с настраиваемым ассоциативным контейнером для списков ребер
Я только начал изучать bgl и столкнулся с проблемой при использовании std::set с пользовательским порядком в качестве контейнера для списков ребер в adjacency_list. Я определяю оператор<, чтобы упорядочить ребра, основываясь на их свойствах, так же, как в примере order_out_edges.cpp. Здесь boost:: edge_unique_ordering - это тег пользовательского свойства.
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). Если я заменю эти вызовы обходным путем, чтобы избежать запроса ребер (source, target), то все будет работать нормально.
Я просмотрел код буста и уверен, что знаю причину, просто не уверен, означает ли это, что я делаю что-то не так, это проблема с буст-кодом или просто недокументированная несовместимость. Функция вызывает set::find(StoredEdge(v)) для контейнера списка внешних ребер u. Теперь сохраненный по умолчанию сохраненный_редж:: оператор<просто сравнивает целевые вершины, но в моем случае вызывается мой пользовательский оператор <, и искомый StoredEdge (v) явно инициализируется по умолчанию без свойств, что, вероятно, является причиной эта проблема. Мне кажется, что ребро (u, v, g) должно искать любое совпадение строго на основе целевой вершины, независимо от того, какой порядок наложен на ребра в контейнере.
Может кто-нибудь пролить свет на то, что я делаю неправильно или не понимаю?
1 ответ
Похоже, вам нужно написать оператор сравнения оболочки, который принимает тип (который будет заполнен с помощью 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
,