You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.08 06:25:06