BGL edge(u, v, g) with custom associative container for edge lists

空扰寡人 提交于 2019-12-22 09:27:41

问题


I've just begun learning bgl and have hit on a problem while using a std::set with a custom ordering as the container for edge lists in an adjacency_list. I define the operator< to order the edges based on their properties, much like in the ordered_out_edges.cpp example. Here boost::edge_unique_ordering is a custom property tag.

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;
    };
}

In general it is working fine, but I am getting iterator exceptions when I use the edge(u, v, g) function. If I replace these calls with a workaround to avoid requesting edges by (source, target) then everything works fine.

I looked through the boost code and I'm pretty sure I know what the cause is, I'm just unsure if it means I'm doing something wrong, it's a problem with the boost code, or just an undocumented incompatibility. The function invokes set::find(StoredEdge(v)) on the out edge list container of u. Now the default stored_edge::operator< just compares target vertices, but in my case my custom operator< is being called, and the StoredEdge(v) which is being looked for is obviously default initialized with no properties, which presumably is the cause of the problem. It seems to me that edge(u, v, g) should be searching for any match based strictly on the target vertex, regardless of what ordering is imposed on the edges within the container.

Can anyone shed some light on what I may be doing wrong or not understanding?


回答1:


It looks like you will need to write a wrapper comparison operator that takes a type (which will be filled in using the StoredEdge type) and compares the results of get_target) on the two inputs using your custom compare function, using something like:

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());
  }
};

then use target_compare<order_by_unique_order<Edge> > as the comparison type in your set.



来源:https://stackoverflow.com/questions/9169276/bgl-edgeu-v-g-with-custom-associative-container-for-edge-lists

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!