c – boost :: dynamic_properties和不可变图形对象

c – boost :: dynamic_properties和不可变图形对象,第1张

概述在使用BGL实现一些算法之后,我试图使用GraphML提供io功能.但是,我没有设法编译一个合适的运算符<<采用const Graph参考. 这是一个简单的例子: // use bundled properties for vertices and edgesstruct VertexProperty{ double error;};typedef boost::adjacency @H_502_2@ 在使用BGL实现一些算法之后,我试图使用GraphML提供io功能.但是,我没有设法编译一个合适的运算符<<采用const Graph参考. 这是一个简单的例子:

// use bundled propertIEs for vertices and edgesstruct VertexProperty{   double error;};typedef boost::adjacency_List< boost::setS,boost::setS,boost::undirectedS,VertexProperty> Graph;typedef typename boost::graph_traits<Graph>::edge_descriptor edge_descriptor;typedef typename boost::graph_traits<Graph>::vertex_descriptor vertex_descriptor;std::ostream& operator<<(std::ostream& os,const Graph& graph){    typedef std::map<vertex_descriptor,std::size_t> IndexMap;    IndexMap index_map;    boost::associative_property_map<IndexMap> index_propertIEs(index_map);    std::size_t i = 0;    for (const vertex_descriptor& v : boost::make_iterator_range(boost::vertices(graph)))        index_propertIEs[v] = i++;    boost::dynamic_propertIEs dp;    typename boost::property_map<Graph,double VertexProperty::*>::const_type error_map = get(&VertexProperty::error,graph);    dp.property("error",error_map);    boost::write_graphml(os,graph,index_propertIEs,dp);    return os;}int main(){  Graph g;  std::cout << g <<std::endl;}

编译失败:

boost/property_map/property_map.hpp:309:44: error: assignment of
read-only location ‘(&((const
boost::adj_List_vertex_property_map,double,const
double&,double
VertexProperty::*>&)pa))->boost::adj_List_vertex_property_map::operator[],const double&,double
VertexProperty::*>(k)’
static_cast(pa)[k] = v;

据我所知,dynamic_propertIEs文档,那些只读检查应该在运行时发生(这不是整个类型擦除的目标之一).当然,如果尝试修改不可变属性,它们应该会失败.但是对wirte write_graphml()的调用需要const参考动力学属性,并且不应该改变任何东西.

陈述问题:

>为什么编译失败?
>我如何正确地做到这一点?
>通过使用其他一些property_map(是/否/哪一个)?

对于(不)运行的示例@coliru.stacked-crooked.com:See here!

问候,
马蒂

解决方法 手头的真正问题是顶点属性映射的类别被推导为LvaluePropertyMap(它是).

但是,LvaluePropertyMap概念有望成为ReadablePropertyMap和WritablePropertyMap的超集.当使用图形属性的const_type时,这会产生问题:它们是左值,但它们是不可写的.

我想出的唯一可行解决方案是将属性映射类型包装为否决类别:

namespace detail {    template <typename Map>        struct readable_only_pmap : Map {            readable_only_pmap(Map map) : Map(map) { }            // overrule the category tag            typedef boost::readable_property_map_tag category;        };}

现在,您可以像这样使用它:

using pmap_t = typename boost::property_map<Graph,double VertexProperty::*>::const_type;detail::readable_only_pmap<pmap_t> error_map = get(&VertexProperty::error,graph);

虽然它几乎相同,但现在dynamic_propertIEs :: property检测到映射只是可读的,并且不会尝试生成put帮助程序(相反,如果尝试put,则会引发异常).

完整代码与演示图:

Live On Coliru

#include <iostream>#include <string>#include <vector>#include <functional>#include <iostream>#include <boost/graph/adjacency_List.hpp>#include <boost/graph/graphml.hpp>// #include <Eigen/Core>// use bundled propertIEs for vertices and edgesstruct VertexProperty{    double error;    // Eigen::Matrix<real,dim,1> location;};typedef boost::adjacency_List< boost::setS,VertexProperty> Graph;typedef typename boost::graph_traits<Graph>::edge_descriptor edge_descriptor;typedef typename boost::graph_traits<Graph>::vertex_descriptor vertex_descriptor;namespace detail {    template <typename Map>        struct readable_only_pmap : Map {            readable_only_pmap(Map map) : Map(map) { }            // overrule the category tag            typedef boost::readable_property_map_tag category;        };}std::ostream& operator<<(std::ostream& os,std::size_t> IndexMap;    IndexMap index_map;    boost::associative_property_map<IndexMap> index_propertIEs(index_map);    std::size_t i = 0;    for (const vertex_descriptor& v : boost::make_iterator_range(boost::vertices(graph)))        index_propertIEs[v] = i++;    using pmap_t = typename boost::property_map<Graph,double VertexProperty::*>::const_type;    detail::readable_only_pmap<pmap_t> error_map = get(&VertexProperty::error,graph);    boost::dynamic_propertIEs dp;    dp.property("error",error_map);    boost::write_graphml(os,dp);    return os;}int main(){  Graph g;  auto v1 = boost::add_vertex(VertexProperty{0.1},g);  auto v2 = boost::add_vertex(VertexProperty{0.2},g);  auto v3 = boost::add_vertex(VertexProperty{0.3},g);  auto v4 = boost::add_vertex(VertexProperty{0.4},g);  auto v5 = boost::add_vertex(VertexProperty{0.5},g);  add_edge(v1,v2,g);  add_edge(v5,g);  add_edge(v4,g);  add_edge(v2,v3,g);  add_edge(v3,v4,v1,g);  std::cout << g <<std::endl;}

输出:(略微重新格式化)

<?xml version="1.0" enCoding="UTF-8"?><graphml xmlns="http://graphml.graphdrawing.org/xmlns" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://graphml.graphdrawing.org/xmlns http://graphml.graphdrawing.org/xmlns/1.0/graphml.xsd"><key ID="key0" for="node" attr.name="error" attr.type="double" /><graph ID="G" edgedefault="undirected" parse.nodeIDs="free" parse.edgeIDs="canonical" parse.order="nodesfirst">    <node ID="n0"> <data key="key0">0.1</data> </node>    <node ID="n1"> <data key="key0">0.2</data> </node>    <node ID="n2"> <data key="key0">0.3</data> </node>    <node ID="n3"> <data key="key0">0.4</data> </node>    <node ID="n4"> <data key="key0">0.5</data> </node>    <edge ID="e0" source="n0" target="n1"> </edge>    <edge ID="e1" source="n4" target="n1"> </edge>    <edge ID="e2" source="n3" target="n1"> </edge>    <edge ID="e3" source="n1" target="n2"> </edge>    <edge ID="e4" source="n2" target="n3"> </edge>    <edge ID="e5" source="n3" target="n0"> </edge></graph></graphml>
@H_502_2@ 总结

以上是内存溢出为你收集整理的c – boost :: dynamic_properties和不可变图形对象全部内容,希望文章能够帮你解决c – boost :: dynamic_properties和不可变图形对象所遇到的程序开发问题。

如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。

欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/langs/1216387.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-06-05
下一篇 2022-06-05

发表评论

登录后才能评论

评论列表(0条)

保存