【发布时间】:2015-02-14 22:54:06
【问题描述】:
C++ 标准容器和分配器为容器使用的指针类型提供 typedef,即:
typename std::vector<T>::pointer
typename std::vector<T>::const_pointer
用于创建 typedef 的实际指针类型是通过std::allocator_traits 确定的
typedef typename std::allocator_traits<Allocator>::pointer pointer;
由于每个容器也有一个value_type typedef,所以pointer typedef 的用途大概是用于某些奇怪的情况,即使用的指针类型其他而不是value_type*。我个人从未见过这样的用例,但我想标准委员会希望提供在容器中使用自定义指针类型的可能性。
问题在于这似乎与为std::allocator_traits 中的函数提供的定义不一致。具体来说,在std::allocator_traits 中我们有construct 函数,定义为:
template <class T, class... Args>
static void construct(Alloc& a, T* p, Args&&... args);
...只是调用a.construct(p, std::forward<Args>(args)...)
但请注意,此函数没有为自定义指针类型做任何规定。参数p 是一个普通的原生指针。
那么,为什么这个函数的定义不是这样的:
template <class... Args>
static void construct(Alloc& a, typename Alloc::pointer p, Args&&... args);
如果没有这个,使用 std::allocator_traits<Alloc>::construct 的容器如果与定义一些自定义指针类型的分配器一起使用,将会失败。
那么,这里发生了什么?还是我首先误解了pointer typedefs 的目的?
【问题讨论】:
-
construct是/必须固定到元素 type。同样与destroy。allocate和deallocate不是。allocate和deallocate都指您正在检查的pointer类型。 这些函数都不处理实际的对象construction和destruction,因此没有保证固定到类型T。但是,construct和destroy都做。 -
@dyp
::std::addressof(*p),而是;) -
pointer != value_type*的整个想法似乎已经(有点)在 C++11 中引入。据我了解,在 C++03 中,容器实现者可以假设pointer == value_type*。我目前正在搜索有关为什么更改它的建议。它似乎与分配器概念文件 (N2654) 和潜在的作用域分配器模型 (N2554) 有关。 -
重读论文后,N2654 - Allocator Concepts (revision 1) 似乎解除了
pointer == value_type*的限制。这可能与使用智能/花式指针有关,例如用于共享内存分配器。