问题描述
我试图将向量存储在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 {
pre>
模板< T>
static inline std :: ostream& (std :: ostream& os,std :: vector< T> const& v){
// ...
等。
另一个稍微简洁的方法是定义一个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 namespacestd
.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),其中顶点包含向量的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!