2015-04-12 16 views
2

我正在试图使用boost的图形库adjacency_list与C++ 11 unorunordered_set。 使用它作为第二个模板参数(即顶点列表)编译罚款,当试图使用它作为“出边”类型(第一个模板参数)时,我得到以下错误: “”C++标准没有'提供这种类型的散列。“ 这里是一个问题的代码:如何使用带有标准unorunordered_set的BGL的adjacency_list作为出界边界列表模板参数

#include <unordered_set> 
#include <boost/config.hpp> 
#include <boost/graph/adjacency_list.hpp> 

struct NodeProperty{ 
    std::string FirstName; 
    std::string LastName; 
}; 

namespace std{ 
    template<> 
    struct hash<NodeProperty> 
    { 
     std::hash<std::string> hasher; 
     size_t operator()(const NodeProperty& key) const 
     { 
      return hasher(key.FirstName)^hasher(key.LastName); 
     } 
    }; 
} 
namespace boost { 
    struct std_unorunordered_setS{}; 

    template <class ValueType> 
    struct container_gen<std_unorunordered_setS, ValueType> { 
     typedef std::unordered_set<ValueType> type; 
    }; 

    template <> 
    struct parallel_edge_traits<std_unorunordered_setS> { 
     typedef disallow_parallel_edge_tag type; 
    }; 
} 

using namespace boost; 

int main(int, char*[]) 
{ 
    typedef adjacency_list< std_unorunordered_setS, std_unorunordered_setS, bidirectionalS, 
     NodeProperty > Graph; 

    typedef graph_traits<Graph>::vertex_descriptor Vertex; 
} 

许多10X, 安德烈

回答

2

出边列表并使用一个实现定义的包装类型。

如果你很好的阅读了这个消息,你可以看到你需要一个类型擦除迭代器封装的散列。您需要这些特例(从detail/adjacency_list.hpp被盗):

namespace std { 

    template <typename V> struct hash<boost::detail::stored_edge<V> > { 
     std::size_t operator()(const boost::detail::stored_edge<V> &e) const { return hash<V>()(e.m_target); } 
    }; 

    template <typename V, typename P> struct hash<boost::detail::stored_edge_property<V, P> > { 
     std::size_t operator()(const boost::detail::stored_edge_property<V, P> &e) const { return hash<V>()(e.m_target); } 
    }; 

    template <typename V, typename I, typename P> struct hash<boost::detail::stored_edge_iter<V, I, P> > { 
     std::size_t operator()(const boost::detail::stored_edge_iter<V, I, P> &e) const { return hash<V>()(e.m_target); } 
    }; 
} 

CAVEAT:我只是使用内置在(使用boost::unordered_set)的hash_setS选择。这样你就不会依赖明确不在公共头文件中的实现细节。

两种口味Live On Coliru

#include <unordered_set> 
#include <boost/config.hpp> 
#include <boost/graph/adjacency_list.hpp> 

struct NodeProperty { 
    std::string FirstName; 
    std::string LastName; 
}; 

namespace std { 
    template <> struct hash<NodeProperty> { 
     std::hash<std::string> hasher; 
     size_t operator()(const NodeProperty &key) const { return hasher(key.FirstName)^hasher(key.LastName); } 
    }; 
} 

namespace std { 
    template <typename V> struct hash<boost::detail::stored_edge<V> > { 
     std::size_t operator()(const boost::detail::stored_edge<V> &e) const { return hash<V>()(e.m_target); } 
    }; 

    template <typename V, typename P> struct hash<boost::detail::stored_edge_property<V, P> > { 
     std::size_t operator()(const boost::detail::stored_edge_property<V, P> &e) const { return hash<V>()(e.m_target); } 
    }; 

    template <typename V, typename I, typename P> struct hash<boost::detail::stored_edge_iter<V, I, P> > { 
     std::size_t operator()(const boost::detail::stored_edge_iter<V, I, P> &e) const { return hash<V>()(e.m_target); } 
    }; 
} 

namespace boost { 
    struct std_unordered_setS {}; 

    template <class ValueType> struct container_gen<std_unordered_setS, ValueType> { 
     typedef std::unordered_set<ValueType> type; 
    }; 

    template <> struct parallel_edge_traits<std_unordered_setS> { typedef disallow_parallel_edge_tag type; }; 
} 

using namespace boost; 

int main() { 
#ifdef USE_STD 
    typedef adjacency_list<std_unordered_setS, std_unordered_setS, bidirectionalS, NodeProperty> Graph; 
#else 
    typedef adjacency_list<hash_setS, hash_setS, bidirectionalS, NodeProperty> Graph; 
#endif 

    // typedef graph_traits<Graph>::vertex_descriptor Vertex; 
} 
+0

许多10倍!奇迹般有效。 – Andrey