使用boost::geometry构建rtree出现编译错误求助
Boost RTree编译失败排查
问题代码
#include <boost/geometry/index/rtree.hpp> #include <boost/geometry.hpp> #include <boost/geometry/geometries/point_xy.hpp> #include <iostream> namespace bg = boost::geometry; namespace bgi = boost::geometry::index; typedef bg::model::d2::point_xy<double> point_2d; class Foo { public: point_2d position; Foo(double x, double y) : position(x, y) {} auto get() const { return position; } }; int main() { bgi::rtree<Foo, bgi::quadratic<16>> rtree; rtree.insert(Foo(1.0, 2.0)); rtree.insert(Foo(3.0, 4.0)); rtree.insert(Foo(5.0, 6.0)); rtree.insert(Foo(7.0, 8.0)); // Define a search box with a certain distance from a given point point_2d search_point(0.0, 0.0); double search_distance = 5.0; point_2d lower_left(search_point.x() - search_distance, search_point.y() - search_distance); point_2d upper_right(search_point.x() + search_distance, search_point.y() + search_distance); bg::model::box<point_2d> search_box(lower_left, upper_right); // Use the rtree to search for instances of Foo within the search box std::vector<Foo> result; rtree.query(bgi::intersects(search_box), std::back_inserter(result)); // Print the results std::cout << "Found " << result.size() << " instances of Foo within the search box" << std::endl; for (const auto& foo : result) std::cout << "Foo at position (" << foo.position.x() << ", " << foo.position.y() << ")" << std::endl; }
编译报错(关键片段)
clang++ --std=c++17 tree.cpp -lboost-geometry 2>&1 | head -n50 In file included from tree.cpp:1: In file included from /usr/include/boost/geometry/index/rtree.hpp:49: /usr/include/boost/geometry/index/indexable.hpp:64:5: error: no matching function for call to 'assertion_failed' BOOST_MPL_ASSERT_MSG( ^~~~~~~~~~~~~~~~~~~~~ ... tree.cpp:27:41: note: in instantiation of template class 'boost::geometry::index::rtree<Foo, boost::geometry::index::quadratic<16, 4>, boost::geometry::index::indexable<Foo>, boost::geometry::index::equal_to<Foo>, boost::container::new_allocator<Foo> >' requested here bgi::rtree<Foo, bgi::quadratic<16>> rtree; ^
错误原因
Boost.Geometry的RTree需要明确知道如何从存储的元素(这里是Foo类实例)中提取用于空间索引的几何对象。默认的indexable适配器仅支持Boost.Geometry原生的几何类型(如point、box),无法自动识别自定义类中的position成员或get()方法,因此触发模板断言错误。
解决方法
需要为Foo类提供一个自定义的indexable getter,告诉RTree如何获取对应的几何对象,以下是两种常用实现方式:
方式1:自定义Indexable函子
定义一个结构体,重载operator()来返回Foo中的position成员:
struct FooIndexable { // 指定返回类型为几何对象类型 using result_type = point_2d; // 接收const Foo&,返回对应的point_2d引用 const point_2d& operator()(const Foo& foo) const { return foo.position; } };
然后在创建RTree时,将这个函子作为第三个模板参数传入:
bgi::rtree<Foo, bgi::quadratic<16>, FooIndexable> rtree;
方式2:特化indexable模板
为Foo类特化boost::geometry::index::indexable模板,让默认适配器能识别它:
namespace boost::geometry::index { template<> struct indexable<Foo> { using result_type = point_2d; const point_2d& operator()(const Foo& foo) const { return foo.position; } }; }
这种方式不需要修改RTree的模板参数,直接使用原来的bgi::rtree<Foo, bgi::quadratic<16>> rtree;即可。
修正后的完整代码(方式1示例)
#include <boost/geometry/index/rtree.hpp> #include <boost/geometry.hpp> #include <boost/geometry/geometries/point_xy.hpp> #include <iostream> namespace bg = boost::geometry; namespace bgi = boost::geometry::index; typedef bg::model::d2::point_xy<double> point_2d; class Foo { public: point_2d position; Foo(double x, double y) : position(x, y) {} auto get() const { return position; } }; // 自定义Indexable函子 struct FooIndexable { using result_type = point_2d; const point_2d& operator()(const Foo& foo) const { return foo.position; } }; int main() { // 指定自定义的Indexable作为第三个模板参数 bgi::rtree<Foo, bgi::quadratic<16>, FooIndexable> rtree; rtree.insert(Foo(1.0, 2.0)); rtree.insert(Foo(3.0, 4.0)); rtree.insert(Foo(5.0, 6.0)); rtree.insert(Foo(7.0, 8.0)); point_2d search_point(0.0, 0.0); double search_distance = 5.0; point_2d lower_left(search_point.x() - search_distance, search_point.y() - search_distance); point_2d upper_right(search_point.x() + search_distance, search_point.y() + search_distance); bg::model::box<point_2d> search_box(lower_left, upper_right); std::vector<Foo> result; rtree.query(bgi::intersects(search_box), std::back_inserter(result)); std::cout << "Found " << result.size() << " instances of Foo within the search box" << std::endl; for (const auto& foo : result) std::cout << "Foo at position (" << foo.position.x() << ", " << foo.position.y() << ")" << std::endl; }
编译提示
确保链接所有必要的Boost库,完整编译命令可能需要:
clang++ --std=c++17 tree.cpp -lboost-geometry -lboost-system -lboost-container
内容的提问来源于stack exchange,提问作者nowox
相关产品推荐
相关产品推荐

