- Java 双重比较
- java - 比较器与 Apache BeanComparator
- Objective-C 完成 block 导致额外的方法调用?
- database - RESTful URI 是否应该公开数据库主键?
我为 boost::adjacency_list
写了一个小包装器:
template <typename T>
using VertexWithIndexProperty =
boost::property<boost::vertex_index_t, int, T>;
template <typename VertexProperty, typename EdgeProperty =
boost::no_property>
class MutableGraph : public boost::adjacency_list< boost::setS,
boost::listS, boost::undirectedS,
VertexWithIndexProperty<VertexProperty>, EdgeProperty> {
public:
using BoostBase =
boost::adjacency_list<boost::setS, boost::listS, boost::undirectedS,
VertexWithIndexProperty<VertexProperty>,
EdgeProperty>;
MutableGraph() {}
MutableGraph(std::size_t n) : BoostBase(n) {}
MutableGraph(const MutableGraph &rhs) : BoostBase(rhs) {}
MutableGraph &operator=(const MutableGraph &rhs) {
static_cast<BoostBase *>(this)->operator=(rhs);
return *this;
}
};
然后我按如下方式使用它:我在集合中收集一些 vertex_descriptors 以创建 boost::filtered_graph
:`
using Graph = MutableGraph<boost::property<vertex_color_t, int>>;
Graph g;
std::set<int> C, H; //vertex_descriptors I collect
...
auto vertex_index_map = get(vertex_index, g);
std::function<bool(vertex_descriptor)> vertexes_filter =
[&vertex_index_map, &C, &H](vertex_descriptor v) {
auto index = vertex_index_map[v];
return C.find(index) != C.end() || H.find(index) != H.end();
};
boost::filtered_graph<Graph, boost::keep_all, decltype(crown_vertexes_filter)>
auxilary(g, boost::keep_all(), crown_vertexes_filter);
一切正常,但是当我尝试获取顶点的任何 property_map 时,例如:`
auto auxilary_vertex_index_map
= get(boost::vertex_index, auxilary);
我收到以下错误:
could not convert
boost::adj_list_vertex_property_map<boost::adjacency_list<boost::setS,
boost::listS, boost::undirectedS,
boost::property<boost::vertex_index_t, int,
boost::property<boost::vertex_color_t, int> >,
boost::no_property, boost::no_property, boost::listS>, int,
int&, boost::vertex_index_t>
to
boost::adj_list_vertex_property_map<MutableGraph<
boost::property<boost::vertex_color_t, int> >,
int,
int&,
boost::vertex_index_t>
我得到这个错误
template <typename G, typename EP, typename VP, typename Property>
typename property_map<G, Property>::type
get(Property p, filtered_graph<G, EP, VP>& g)
{
return get(p, const_cast<G&>(g.m_g));
}
在 filtered_graph.hpp
中。
我不明白为什么会这样,是因为我的包装器还是因为我决定使用嵌套属性而不是捆绑属性。
提前致谢!
最佳答案
嵌套属性被称为“内部属性”。他们不是你的问题。
相反,您的问题出在 VertexContainerSelector 参数 ( boost::listS
) 上。它导致 vertex_descriptor
类型为
您已经知道这一点,这就是您添加一个属性作为顶点索引图的原因。但是,您没有预料到的是,它生成了 vertex_index
的结果类型。属性映射 ( boost::property_map<Graph, vertex_index_t>::type
) 不同,因此 filtered_graph
中的转发包装器不再符合要求:
template <typename G, typename EP, typename VP, typename Property>
typename property_map<G, Property>::type
get(Property p, filtered_graph<G, EP, VP>& g)
{
return get(p, const_cast<G&>(g.m_g));
}
如果您负担得起,只需切换到 vecS
,我会去的。否则,请仔细考虑您的要求和影响。值得注意的是,您的 VertexContainerSelector
选择listS
结果 vertex_descriptor
具有引用和迭代器稳定性。任何vertex_descriptor
来自 filtered_graph 的数据应该对主图有效,反之亦然。为什么不只保留相同的 map :
#include <boost/graph/adjacency_list.hpp>
#include <boost/graph/filtered_graph.hpp>
#include <boost/graph/graph_utility.hpp> // print_graph
template <typename T> using AddIndex = boost::property<boost::vertex_index_t, int, T>;
template <
typename VertexProperty,
typename EdgeProperty = boost::no_property,
typename Base = boost::adjacency_list<boost::setS, boost::listS, boost::undirectedS, AddIndex<VertexProperty>, EdgeProperty> >
struct MutableGraph : Base {
using BoostBase = Base;
MutableGraph(std::size_t n = 0) : BoostBase(n) {}
using BoostBase::operator=;
};
int main() {
using Graph = MutableGraph<boost::property<boost::vertex_color_t, int> >;
using vertex_descriptor = Graph::vertex_descriptor;
Graph g;
auto a = add_vertex({1, 0}, g);
auto b = add_vertex({2, 0}, g);
auto c = add_vertex({3, 0}, g);
auto d = add_vertex({4, 0}, g);
add_edge(a, b, g);
add_edge(a, c, g);
add_edge(b, d, g);
std::set<int> C{1,2}, H{/*3,*/4}; // vertex_descriptors I collect
auto id = get(boost::vertex_index, g);
std::function<bool(vertex_descriptor)> vertexes_filter = [id, &C, &H](vertex_descriptor v) {
auto index = id[v];
return C.count(index) || H.count(index);
};
boost::filtered_graph<Graph, boost::keep_all, decltype(vertexes_filter)> auxilary(g, boost::keep_all(), vertexes_filter);
auto aux_id = id;
print_graph(g, id, std::cout << "\n---- Original\n");
print_graph(auxilary, aux_id, std::cout << "\n---- Filtered\n");
}
打印:
---- Original
1 <--> 2 3
2 <--> 1 4
3 <--> 1
4 <--> 2
---- Filtered
1 <--> 2
2 <--> 1 4
4 <--> 2
这正是您想要的。
注意代码中的简化。你的MutableGraph
类可以写成:
template <
typename VertexProperty,
typename EdgeProperty = boost::no_property,
typename Base = boost::adjacency_list<boost::setS, boost::listS, boost::undirectedS, AddIndex<VertexProperty>, EdgeProperty> >
struct MutableGraph : Base {
using BoostBase = Base;
MutableGraph(std::size_t n = 0) : BoostBase(n) {}
using BoostBase::operator=;
};
虽然在这个例子中甚至可以简单地省略这两个成员(编译器仍会正确生成 operator=
)。
¹ 过滤后的可能除外...
根据评论更新:您可以通过专门化 boost::property_map<>
来“自动化”类型转发特点:
namespace boost {
// overriding the typedef to take the types from the BoostBase instead:
template <typename Tag, typename... Args>
struct property_map<MyGraph<Args...>, Tag> : property_map<typename MyGraph<Args...>::BoostBase, Tag> {
};
}
就是这样。现在您可以在一个不知道它正在处理哪种类型的图形的函数中进行打印:
template <typename WhateverGraph>
void some_naive_user_function(WhateverGraph const& g, std::ostream& os) {
// we don't know whether WhateverGraph is filtered or not, but we don't care
print_graph(g, get(boost::vertex_index, g), os);
}
get(boost::vertex_index, g)
由于特化才有效:
boost::filtered_graph<Graph, boost::keep_all, decltype(vertexes_filter)> auxilary(g, boost::keep_all(), vertexes_filter);
some_naive_user_function(g, std::cout << "\n---- Origina (via naive user function)\n");
some_naive_user_function(auxilary, std::cout << "\n---- Filtered (via naive user function)\n");
关于c++ - boost::get with boost::filtered_graph on adjacency_list with netsed 属性,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53490593/
我正在尝试使用boost.spirit的qi库解析某些内容,而我遇到了一个问题。根据spirit docs,a >> b应该产生类型为tuple的东西。但这是boost::tuple(又名 fusio
似乎有/正在努力做到这一点,但到目前为止我看到的大多数资源要么已经过时(带有死链接),要么几乎没有信息来实际构建一个小的工作样本(例如,依赖于boost program_options 以构建可执行文
我对 Boost.Log 的状态有点困惑。这是 Boost 的官方部分,还是尚未被接受?当我用谷歌搜索时,我看到一些帖子谈论它在 2010 年是如何被接受的,等等,但是当我查看最后一个 Boost 库
Boost 提供了两种不同的实现 string_view ,这将成为 C++17 的一部分: boost::string_ref在 utility/string_ref.hpp boost::stri
最近,我被一家GIS公司雇用来重写他们的旧地理信息库。所以我目前正在寻找一个好的计算几何库。我看过CGAL,这真是了不起,但是我的老板想要免费的东西。 所以我现在正在检查Boost.Geometry。
假设我有一个无向图 G。假设我添加以下内容 add_edge(1,2,G); add_edge(1,3,G); add_edge(0,2,G); 现在我再说一遍: add_edge(0,2,G); 我
我使用 CMake 来查找 Boost。找到了 Boost,但 CMake 出错了 Imported targets not available for Boost version 请参阅下面的完整错
我是 boost::fusion 和 boost::mpl 库的新手。谁能告诉我这两个库之间的主要区别? 到目前为止,我只使用 fusion::vector 和其他一些简单的东西。现在我想使用 fus
这个问题已经有答案了: 已关闭10 年前。 Possible Duplicate: What are the benefits of using Boost.Phoenix? 所以我开始阅读 boos
我正在尝试获得一个使用 Boost.Timer 的简单示例,用于一些秒表性能测量,但我不明白为什么我无法成功地将 Boost.Timer 链接到 Boost.Chrono。我使用以下简单脚本从源代码构
我有这样的东西: enum EFood{ eMeat, eFruit }; class Food{ }; class Meat: public Food{ void someM
有人可以告诉我,我如何获得boost::Variant处理无序地图? typedef boost::variant lut_value;unordered_map table; 我认为有一个用于boo
我对 Boost.Geometry 中的环和多边形感到困惑。 在文档中,没有图形显示什么是环,什么是多边形。 谁能画图解释两个概念的区别? 最佳答案 在 Boost.Geometry 中,多边形被定义
我正在使用 boost.pool,但我不知道何时使用 boost::pool<>::malloc和 boost::pool<>::ordered_malloc ? 所以, boost::pool<>:
我正在尝试通过 *boost::fast_pool_allocator* 使用 *boost::container::flat_set*。但是,我收到编译错误。非常感谢您的意见和建议。为了突出这个问题
sau_timer::sau_timer(int secs, timerparam f) : strnd(io), t(io, boost::posix_time::seconds(secs)
我无法理解此功能的文档,我已多次看到以下内容 tie (ei,ei_end) = out_edges(*(vi+a),g); **g**::out_edge_iterator ei, ei_end;
我想在 C++ 中序列化分层数据结构。我正在处理的项目使用 boost,所以我使用 boost::property_tree::ptree 作为我的数据节点结构。 我们有像 Person 这样的高级结
我需要一些帮助来解决这个异常,我正在实现一个 NPAPI 插件,以便能够使用来自浏览器扩展的本地套接字,为此我正在使用 Firebreath 框架。 对于套接字和连接,我使用带有异步调用的 Boost
我尝试将 boost::bind 与 boost::factory 结合使用但没有成功 我有这个类 Zambas 有 4 个参数(2 个字符串和 2 个整数)和 class Zambas { publ
我是一名优秀的程序员,十分优秀!