2015-04-12 17 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