我尝试实现std::list
(MSVC)。还有一件事我无法理解:
template <class _Value_type, class _Voidptr> // voidptr? For what?
struct _List_node { // list node
using value_type = _Value_type;
using _Nodeptr = _Rebind_pointer_t<_Voidptr, _List_node>; // what is the purpose of such rebind?
...
}
我明白分配器重新绑定(bind)的原因,但是指针呢?我为什么要使用它以及在哪里使用它?
UPD:我明白了,什么是重新绑定(bind)。我的意思是,为什么不只是 _Nodeptr*
呢?为什么我需要重新绑定(bind)? (感谢 Evg)
最佳答案
这个问题的答案也来自分配器。我们来看看如何_Rebind_pointer_t
是 defined :
template <class _Ptr, class _Ty>
using _Rebind_pointer_t = typename pointer_traits<_Ptr>::template rebind<_Ty>;
也就是说,我们有
template <class _Value_type, class _Voidptr>
struct _List_node {
using _Nodeptr = typename pointer_traits<_Voidptr>::template rebind<_List_node>;
// ...
}
现在让我们看看如何_List_node
是 used :
using _Node = _List_node<_Ty, typename _Alty_traits::void_pointer>;
实际上,我们重新绑定(bind)了分配器的 void_pointer
至_List_node
指针。需要这个技巧来支持内部使用花式指针的分配器。
可以在 Boost.Interprocess 库中找到这样一个示例。它有boost::interprocess::allocator :
An STL compatible allocator that uses a segment manager as memory source. The internal pointer type will of the same type (raw, smart) as
typename SegmentManager::void_pointer
type. This allows placing the allocator in shared memory, memory mapped-files, etc...
例如我们可以这样写
namespace bi = boost::interprocess;
using Allocator = bi::allocator<int, bi::managed_shared_memory::segment_manager>;
std::list<int, Allocator> list(/* allocator object */);
现在std::allocator_traits<decltype(list)::allocator_type>::void_pointer
不会void*
与默认分配器一样,但是 boost::interprocess::offset_ptr<void, ...>
。结果,_Nodeptr
不会_Nodeptr*
,但是boost::interprocess::offset_ptr<_Nodeptr, ...>
.
关于c++ - 指针重新绑定(bind)的目的是什么?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/65262899/