2016-11-18 2 views
2

Я пытаюсь сохранить векторы в вершинах графа повышения. У меня проблемы с чтением из файла с помощью функции boost :: read_graphviz. Компиляция разрывов из-за строки, которая связывает содержимое вершин с динамическими свойствами.читать boost graph (boost :: read_graphviz) где вершина содержит вектор

Вот упрощенный вариант (назовем его test.cpp):

#include <iostream> 
#include <vector> 
#include <boost/graph/adjacency_list.hpp> 
#include <boost/graph/graphviz.hpp> 
#include <fstream> 

struct Vertex 
{ 
    std::vector<int> p; 
}; 

struct Edge 
{ 
    double w; 
}; 


// this should be necessary, but is not 'seen' by compiler 
std::ostream & 
operator << (std::ostream &OUT, const std::vector<int> &P) 
    { 
    OUT << P.size() << " "; 
    for(int i = 0; i < P.size(); ++i) 
     OUT << P[i] << " "; 
    return OUT; 
    } 

// also doesn't help (and also should not be necessary as ostringstream is derived from ostream (or?) 
std::ostringstream & 
operator << (std::ostringstream &OUT, const std::vector<int> &P) 
    { 
    OUT << P.size() << " "; 
    for(int i = 0; i < P.size(); ++i) 
     OUT << P[i] << " "; 
    return OUT; 
    } 



int main() 
{ 
    typedef boost::adjacency_list<boost::setS, boost::setS, boost::bidirectionalS, Vertex, Edge> 
    Graph; 

    Graph 
    graph; 

    std::ifstream 
    in; 

    boost::dynamic_properties 
    dp; 

    dp.property("vector", get( &Vertex::p, graph)); // the critical line 
    dp.property("value", get( &Edge::w, graph)); 

    boost::read_graphviz(in, graph, dp); 
} 

Я компилировать это с помощью

g++ test.cpp -lboost_graph 

и получить следующее сообщение об ошибке (только первый блок):

In file included from /usr/include/boost/graph/graphviz.hpp:25:0, 
       from boost_graph_test.cpp:4: 
/usr/include/boost/property_map/dynamic_property_map.hpp: In instantiation of ‘std::string boost::detail::dynamic_property_map_adaptor<PropertyMap>::get_string(const boost 
::any&) [with PropertyMap = boost::adj_list_vertex_property_map<boost::adjacency_list<boost::setS, boost::setS, boost::bidirectionalS, Vertex, Edge>, std::vector<int>, std 
::vector<int>&, std::vector<int> Vertex::*>; std::string = std::basic_string<char>]’: 
boost_graph_test.cpp:58:1: required from here 
/usr/include/boost/property_map/dynamic_property_map.hpp:180:9: error: no match for ‘operator<<’ (operand types are ‘std::ostringstream {aka std::basic_ostringstream<char>}’ and ‘std::vector<int>’) 
    out << get_wrapper_xxx(property_map_, any_cast<typename boost::property_traits<PropertyMap>::key_type>(key)); 

Вопрос касается линии, обозначенной как критическая. Когда он комментируется, он компилируется. Что я делаю не так?

ответ

1

Это FAQ.

Вам необходимо объявить перегрузку в пространстве имен, связанных с ADL. Поскольку int не имеет связанного пространства имен, вы должны определить его в пространстве имен std.

Сделайте это файло-статическим, чтобы избежать конфликтов ODR.

namespace std { 

    template <T> 
    static inline std::ostream& operator<<(std::ostream& os, std::vector<T> const& v) { 

      // ... 

т.д.


Еще немного чище подход заключается в определении UDT (определенный пользователь типа), что позволяет правильно подключить потоковыми перегрузки в собственном пространстве имен.

Вот пример, который показывает write_graphviz стороны: Using two objects as hash key for an unordered_map or alternatives

+0

Великого, спасибо. Ожидаемая проблема, связанная с повышением ... Сейчас она работает, предоставляя как оператора << и оператора >> – redo

+0

@redo Не мог бы поделиться кодом для оператора << и оператора >>? – nevrome

+1

@ nevrome как насчет http://coliru.stacked-crooked.com/a/bb5fb13f9c2e852d – sehe

Смежные вопросы