我有一个带有自定义属性的增强图。我想复印一份。我按照以下方式尝试了,但出现了很多编译错误。
这就是我所做的:
using BGType = boost::adjacency_list<boost::vecS, boost::vecS, boost::bidirectionalS,
// Vertex Properties...
vertexProps,
// Edge Propereties...
edgeProps,
// Graph Properties
graphProps>;
vertexProps.h
class vertexProps {
public:
explicit vertexProps(const std::string *moduleName = nullptr, const std::string *name = nullptr,
long refPtr = 0 )
: _refPtr(refPtr),
{
_moduleName = moduleName ? *moduleName : "";
_name = name ? *name : "";
};
struct CustomVertexCopy {
void operator()(const vertexProps& source_vertex, vertexProps& target_vertex) const {
target_vertex._refPtr = source_vertex._refPtr;
target_vertex._moduleName = source_vertex._moduleName;
target_vertex._name = source_vertex._name;
}
edgeProps.h
class edgeProps {
public:
explicit edgeProps(std::string name = "")
: _name(name){};
std::string _name;
};
struct CustomEdgeCopy {
void operator()(const edgeProps& source_edge, edgeProps& target_edge) const {
target_edge._name = source_edge._name;
}
};
一些函数.cpp
OnClick(BGType* bGraph)
{
// some code
BGType* oldBg = new BGType;
boost::copy_graph(bGraph, oldBg, boost::vertex_copy(CustomVertexCopy()));
boost::copy_graph(bGraph, oldBg, boost::edge_copy(CustomEdgeCopy()));
// some code
}
我哪里错了?
我还有一个疑问。
如果 grpah 很大,这种深度复制会影响性能吗?
如果是的话,有什么办法可以避免吗?
命名参数是链接的,因此您可以在一个地方传递任意数量的参数:
boost::copy_graph( //
g1, g2, //
boost::vertex_copy(CustomVertexCopy{}) //
.edge_copy(CustomEdgeCopy{}));
请注意,
.edge_copy
链接在 vertex_copy()
命名参数对象上。
然后,仍然无法编译,因为自定义复制器应该采用描述符,而不是捆绑引用:
struct CustomVertexCopy {
BGType const& g1;
BGType& g2;
void operator()(BGType::vertex_descriptor v1, BGType::vertex_descriptor v2) const {
vertexProps const& p1 = g1[v1];
vertexProps& p2 = g2[v2];
p2._refPtr = p1._refPtr;
p2._moduleName = p1._moduleName;
p2._name = p1._name;
}
};
现在一切正常了:
#include <boost/graph/adjacency_list.hpp>
#include <boost/graph/copy.hpp>
#include <boost/graph/graphviz.hpp>
class vertexProps {
public:
explicit vertexProps(std::string const* mn = nullptr, std::string const* n = nullptr, long refPtr = 0)
: _refPtr(refPtr) {
_moduleName = mn ? *mn : "";
_name = n ? *n : "";
}
std::string _moduleName;
std::string _name;
long _refPtr;
};
class edgeProps {
public:
explicit edgeProps(std::string name = "") : _name(name){};
std::string _name;
};
struct graphProps {};
using BGType = boost::adjacency_list< //
boost::vecS, boost::vecS, boost::bidirectionalS, //
vertexProps, edgeProps, graphProps>;
struct CustomVertexCopy {
BGType const& g1;
BGType& g2;
void operator()(BGType::vertex_descriptor v1, BGType::vertex_descriptor v2) const {
vertexProps const& p1 = g1[v1];
vertexProps& p2 = g2[v2];
p2._refPtr = p1._refPtr;
p2._moduleName = p1._moduleName;
p2._name = p1._name;
}
};
struct CustomEdgeCopy {
BGType const& g1;
BGType& g2;
void operator()(BGType::edge_descriptor e1, BGType::edge_descriptor e2) const {
g2[e2]._name = g1[e1]._name;
}
};
int main() {
BGType g1(3);
std::string const names[] {"Hello", "world", "Goodbye", "moon", "Greetings", "Cosmos"};
g1[0] = vertexProps{names + 0, names + 1, 111};
g1[1] = vertexProps{names + 2, names + 3, 222};
g1[2] = vertexProps{names + 4, names + 5, 333};
add_edge(0, 1, edgeProps{"one"}, g1);
add_edge(2, 0, edgeProps{"two"}, g1);
BGType g2;
boost::copy_graph( //
g1, g2, //
boost::vertex_copy(CustomVertexCopy{g1, g2}) //
.edge_copy(CustomEdgeCopy{g1, g2}));
boost::dynamic_properties dp;
dp.property("node_id", get(boost::vertex_index, g2));
dp.property("moduleName", get(&vertexProps::_moduleName, g2));
dp.property("name", get(&vertexProps::_name, g2));
dp.property("ref", get(&vertexProps::_refPtr, g2));
dp.property("name", get(&edgeProps::_name, g2));
write_graphviz_dp(std::cout, g2, dp);
}
打印
digraph G {
0 [moduleName=Hello, name=world, ref=111];
1 [moduleName=Goodbye, name=moon, ref=222];
2 [moduleName=Greetings, name=Cosmos, ref=333];
0->1 [name=one];
2->0 [name=two];
}
简化!只需使属性可复制,就可以了,代码行数减少了 20 行,大约减少了 30% 的错误/悲观空间:
#include <boost/graph/adjacency_list.hpp>
#include <boost/graph/copy.hpp>
#include <boost/graph/graphviz.hpp>
class vertexProps {
public:
vertexProps(vertexProps const&) = default;
vertexProps& operator=(vertexProps const&) = default;
explicit vertexProps(std::string const* mn = nullptr, std::string const* n = nullptr, long refPtr = 0)
: _refPtr(refPtr) {
_moduleName = mn ? *mn : "";
_name = n ? *n : "";
}
std::string _moduleName;
std::string _name;
long _refPtr;
};
class edgeProps {
public:
edgeProps(edgeProps const&) = default;
edgeProps& operator=(edgeProps const&) = default;
explicit edgeProps(std::string name = "") : _name(name){};
std::string _name;
};
struct graphProps {};
using BGType = boost::adjacency_list< //
boost::vecS, boost::vecS, boost::bidirectionalS, //
vertexProps, edgeProps, graphProps>;
int main() {
BGType g1(3);
std::string const names[] {"Hello", "world", "Goodbye", "moon", "Greetings", "Cosmos"};
g1[0] = vertexProps{names + 0, names + 1, 111};
g1[1] = vertexProps{names + 2, names + 3, 222};
g1[2] = vertexProps{names + 4, names + 5, 333};
add_edge(0, 1, edgeProps{"one"}, g1);
add_edge(2, 0, edgeProps{"two"}, g1);
BGType g2;
boost::copy_graph(g1, g2);
boost::dynamic_properties dp;
dp.property("node_id", get(boost::vertex_index, g2));
dp.property("moduleName", get(&vertexProps::_moduleName, g2));
dp.property("name", get(&vertexProps::_name, g2));
dp.property("ref", get(&vertexProps::_refPtr, g2));
dp.property("name", get(&edgeProps::_name, g2));
write_graphviz_dp(std::cout, g2, dp);
}
仍在打印
digraph G {
0 [moduleName=Hello, name=world, ref=111];
1 [moduleName=Goodbye, name=moon, ref=222];
2 [moduleName=Greetings, name=Cosmos, ref=333];
0->1 [name=one];
2->0 [name=two];
}