其中顶点包含向量

其中顶点包含向量

本文介绍了阅读增强图(boost :: read_graphviz),其中顶点包含向量的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我试图将向量存储在boost图的顶点。
我遇到了使用boost :: read_graphviz函数从文件读取的问题。编译由于将顶点内容与动态属性关联而产生的断点。



这是一个简化版本(我们称之为test.cpp):

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

结构顶点
{
std :: vector< int>磷;
};

结构边缘
{
double w;
};


//这应该是必须的,但不是编译器'看到'
std :: ostream&
操作符<< (std :: ostream& OUT,const std :: vector< int>& P)
{
OUT<< P.size()<< ;
for(int i = 0; i< P.size(); ++ i)
OUT<< P [i]<< ;
返回OUT;
}

//也没有帮助(也不应该有必要,因为ostringstream是从ostream(或?)
std :: ostringstream&
运算符<<<<(std :: ostringstream& OUT,const std :: vector< int>& P)
{
OUT<<< P.size()< ;;
for(int i = 0; i< P.size(); ++ i)
OUT< P lt;<<;
返回OUT;
}



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

图形
图形;

std :: ifstream
in;

boost :: dynamic_properties
dp;

dp.property(vector,get(& Vertex :: p,graph)); / /关键线
dp.property(value,get(& Edge :: w,graph));

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

$ / code>

我使用

  g ++ test.cpp -lboost_graph 

并获取以下内容错误消息(仅限第一个块):

 在/usr/include/boost/graph/graphviz.hpp:25包含的文件中:0,来自boost_graph_test.cpp的
:4:
/usr/include/boost/property_map/dynamic_property_map.hpp:在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>顶点:: *取代; std :: string = std :: basic_string< char>'':
boost_graph_test.cpp:58:1:从这里需要
/usr/include/boost/property_map/dynamic_property_map.hpp:180:9 :错误:'operator<'(操作数类型是'std :: ostringstream {aka std :: basic_ostringstream< char>'和'std :: vector< int>')
out< < get_wrapper_xxx(property_map_,any_cast< typename boost :: property_traits< PropertyMap> :: key_type>(key));

问题在于标记为关键的行。当被注释掉时,它会被编译。我究竟做错了什么?

解决方案

这是一个常见问题解答。与ADL相关的命名空间中的过载。由于 int 没有关联的名称空间,所以您必须在命名空间 std 中定义它。



使其成为静态文件,以避免ODR冲突。

  namespace std {

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

// ...
pre>

等。




另一个稍微简洁的方法是定义一个UDT(用户定义的类型),它允许你在自己​​的命名空间中正确地连接流重载。



下面是一个示例,显示 write_graphviz side:


I am trying to store vectors in the vertices of the boost graph. I am running into problems reading from file using the boost::read_graphviz function. Compiling breaks due to the line that relates the vertex content to the dynamic properties.

Here is a simplified version (let's call it 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);
}

I compile this using

g++ test.cpp -lboost_graph

And get the following error message (first block only):

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

The issue is the line marked as critical. When commented out, it compiles. What am I doing wrong?

解决方案

This is a FAQ.

You need to declare the overload in an ADL-associated namespace. Because int has no associated namespace, you must define it in namespace std.

Make it file-static so you avoid ODR conflicts.

namespace std {

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

          // ...

etc.


Another slightly cleaner approach is to define a UDT (user-defined type) that allows you to properly hook up streaming overloads in your own namespace.

Here's a sample that shows the write_graphviz side: Using two objects as hash key for an unordered_map or alternatives

这篇关于阅读增强图(boost :: read_graphviz),其中顶点包含向量的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

09-05 04:27