忽略std :: vector <char>的自定义分配器</char>

时间:2013-03-05 13:26:17

标签: c++ c++11 allocator

我试图为std::vector<char>使用自定义分配器,但我注意到std::vector不需要/使用我的分配器中的任何成员函数。这怎么可能?

#include <vector>

struct A : private std::allocator<char> {
   typedef std::allocator<char> alloc;
   using alloc::value_type;
   using alloc::pointer;
   using alloc::const_pointer;
   using alloc::difference_type;
   using alloc::size_type;
   using alloc::rebind;
   // member functions have been removed, since the program compiles without them
};

int main() {
    std::vector<char, A> v;
    v.resize(4000);
    for (auto& c : v)
      if (c)
         return 1; // never happens in my environment
   return 0; // all elements initialized to 0. How is this possible?
}

我使用在线C ++ 11编译器(LiveWorkSpace)尝试上述程序,提供g ++ 4.7.2,4.8和4.6.3。

基本上allocate()deallocate()construct()destroy()未在我的分配器中定义,但程序编译并且所有元素都将初始化为0。

2 个答案:

答案 0 :(得分:14)

GCC标准库将始终重新绑定提供的分配器,因此在内部它会执行类似这样的操作(在C ++ 03中):

typedef Alloc::template rebind<value_type>::other _Allocator_type;

(在C ++ 11中它使用allocator_traits但在这种情况下结果是相同的。)

然后,向量在内部存储该类型的对象,并将其用于所有(de)分配。

由于您尚未在分配器中定义rebind成员模板,因此您刚刚从基类重新声明了该模板,重新绑定的结果为std::allocator<value_type>而不是您自己的类型。 std::allocator当然提供了所有这些功能,因此无论您是否使用自己的类型定义它们,都会使用这些功能。

您可以通过将其添加到using alloc::rebind;的分配器整数来修复它,以便vector在内部存储和使用A

struct A : private std::allocator<char> {
    template<typename U>
      struct rebind {
        typedef A other;
      };

N.B。这只适用于vector,因为vector并不严格需要重新绑定分配器(用户需要使用allocator<value_type>实例化模板,但GCC的vector仍然重新绑定因此,如果用户实例化vector<int, std::allocator<char>>它仍然有效。)对于基于节点的容器,例如std::set,您的分配器必须是可以反弹的模板,因为容器需要分配其内部节点类型,而不是value_type,因此需要Alloc::rebind<internal_node_type>::other才有效。

答案 1 :(得分:7)

vector将重新绑定分配器。当您将其带入std::allocator的范围时,A::rebind<T>::other将只是std::allocator<T>。所以一切正常。