具有boost rtrees的Hinnant的堆栈分配器:编译失败

时间:2019-08-06 04:06:55

标签: c++ c++11 boost memory-management allocator

我正在尝试将Howard Hinnant的stack_alloc与boost rtrees结合使用,如以下示例所示:

#include "stack_alloc.h"
#include <boost/geometry/index/rtree.hpp>

using NodePoint = boost::geometry::model::point<double, 2, boost::geometry::cs::cartesian>;
using Linear = boost::geometry::index::linear<8, 2>;
using RTree =
    boost::geometry::index::rtree<NodePoint, Linear, boost::geometry::index::indexable<NodePoint>,
                                  boost::geometry::index::equal_to<NodePoint>,
                                  stack_alloc<NodePoint, 100>>;

int main()
{
    RTree my_tree{};

    return 0;
}

这无法使用相当大的模板错误堆栈进行编译。我认为问题的核心是:

  

/usr/local/include/boost/geometry/index/detail/rtree/node/variant_static.hpp:26:7:错误:无效使用了不完整的类型'class boost :: geometry :: index :: detail: :rtree ::分配器,100>,boost :: geometry :: model :: point,boost :: geometry :: index :: linear <8,2>,boost :: geometry :: model :: box>,boost: :geometry :: index :: detail :: rtree :: node_variant_static_tag>'

这是coliru上的完整示例,带有完整错误。

这是怎么了?

我尝试将stack_alloc与各种boost::container::static_vectorboost::container::map之类的增强集合一起使用,并且效果很好。 我还尝试使用this SO reply中的另一个stack_allocator实现,并得到相同的错误。

此外,我知道Howard Hinnant有一个更新的实现,即short_alloc。我尝试使用它,但是此实现没有默认的ctor,要求我们在构建时提供存储。由于boost将分配器作为模板参数并在内部实例化它,因此我无法找到一种方法来完成这项工作,但是如果有办法,我会很乐意使用它。 stack_alloc和/ vs short_alloc的更多信息:123

1 个答案:

答案 0 :(得分:5)

问题的核心本质上是循环依赖。

构造RTree会导致rtree<...>模板实例化,其中包括typedef node_pointer = allocators_type::node_pointer,它触发allocators_type的实例化,即detail::rtree::allocators<...>,它具有一个detail::rtree::node_alloc<...>的基类,在其定义中将分配器重新绑定到节点类型。节点类型是detail::rtree::variant_leaf<...>detail::rtree::variant_internal_node<...>的变体。

但是stack_alloc需要sizeof(T),因此variant类型中包含的两个模板都将被实例化,而实例化variant_internal_node时,它需要Allocators::node_pointer,因此Allocators必须实例化,但这不是我们正在实例化的过程!

我建议尝试short_alloc并将分配器传递给容器。因为它将存储与分配器类型分开,所以它不应该要求模板类型的完整性,否则会造成麻烦。