带有 boost rtrees 的 Hinnant 堆栈分配器:编译失败
Hinnant's stack allocator with boost rtrees: compilation failure
我正在尝试将 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: error: invalid use of incomplete type 'class boost::geometry::index::detail::rtree::allocators, 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_vector
和 boost::container::map
,并且效果很好。
我还尝试使用 this SO reply 中的另一个 stack_allocator
实现并得到了同样的错误。
此外,我知道 Howard Hinnant 有一个更新的实现,即 short_alloc
. I tried using it, but this implementation has no default ctor and requires us to provide the storage at construction time. Since boost
takes the allocator as a template parameter and instantiates it internally, I could not find a way to make this work, but will happily use it if there is a way. Further info for stack_alloc
and/vs short_alloc
: , , 3
问题的核心本质上是循环依赖。
构造 RTree
会导致 rtree<...>
模板实例化,其中包含一个 typedef node_pointer = allocators_type::node_pointer
,它会触发 allocators_type
的实例化,即 detail::rtree::allocators<...>
,它具有 detail::rtree::node_alloc<...>
的基数 class,它在其定义中将分配器重新绑定到节点类型。节点类型是 detail::rtree::variant_leaf<...>
和 detail::rtree::variant_internal_node<...>
.
的变体
但是 stack_alloc
需要 sizeof(T)
,因此 variant
类型中包含的两个模板都被实例化,并且在实例化 variant_internal_node
时需要 Allocators::node_pointer
, 所以 Allocators
必须实例化,但这不就是我们正在实例化的东西吗!
我建议尝试 short_alloc
并将分配器传递给容器。因为它把存储和分配器类型分开了,所以应该不需要模板类型的完整性,打破循环。
我正在尝试将 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: error: invalid use of incomplete type 'class boost::geometry::index::detail::rtree::allocators, 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_vector
和 boost::container::map
,并且效果很好。
我还尝试使用 this SO reply 中的另一个 stack_allocator
实现并得到了同样的错误。
此外,我知道 Howard Hinnant 有一个更新的实现,即 short_alloc
. I tried using it, but this implementation has no default ctor and requires us to provide the storage at construction time. Since boost
takes the allocator as a template parameter and instantiates it internally, I could not find a way to make this work, but will happily use it if there is a way. Further info for stack_alloc
and/vs short_alloc
:
问题的核心本质上是循环依赖。
构造 RTree
会导致 rtree<...>
模板实例化,其中包含一个 typedef node_pointer = allocators_type::node_pointer
,它会触发 allocators_type
的实例化,即 detail::rtree::allocators<...>
,它具有 detail::rtree::node_alloc<...>
的基数 class,它在其定义中将分配器重新绑定到节点类型。节点类型是 detail::rtree::variant_leaf<...>
和 detail::rtree::variant_internal_node<...>
.
但是 stack_alloc
需要 sizeof(T)
,因此 variant
类型中包含的两个模板都被实例化,并且在实例化 variant_internal_node
时需要 Allocators::node_pointer
, 所以 Allocators
必须实例化,但这不就是我们正在实例化的东西吗!
我建议尝试 short_alloc
并将分配器传递给容器。因为它把存储和分配器类型分开了,所以应该不需要模板类型的完整性,打破循环。