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

Mar*_*tin 10 c++ allocator c++11

我试图使用自定义分配器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?
}
Run Code Online (Sandbox Code Playgroud)

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

基本上allocate(),deallocate(),construct()destroy()不是在我的定义分配器,但在程序编译,所有的元素将被初始化为0.

Jon*_*ely 14

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

typedef Alloc::template rebind<value_type>::other _Allocator_type;
Run Code Online (Sandbox Code Playgroud)

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

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

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

你可以通过将它添加到你的allocator intead来修复它,using alloc::rebind;以便vectorA内部存储和使用:

struct A : private std::allocator<char> {
    template<typename U>
      struct rebind {
        typedef A other;
      };
Run Code Online (Sandbox Code Playgroud)

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

  • @AndyProwl - 分配器确实应该是模板模板参数,但是在设计STL(注:**STL**,而不是**标准库**)时模板模板参数不存在,所以`rebind`是创建. (5认同)
  • 请开始你自己的问题而不是劫持这个评论 (3认同)
  • 内部字段未分配,它们只是对象的成员,因此存在于对象存在的内存中.嵌套容器与任何其他元素类型没有区别:对象本身及其成员将被放置在容器分配的内存中,如果它分配自己的内存(作为嵌套容器),那么该内存将位于地址的其他位置空间.请参阅`std :: scoped_allocator_adaptor`以获取导致元素从其容器继承分配器的实用程序 (2认同)

R. *_*des 7

vector将重新绑定分配器.当你把它带入范围时std::allocator,A::rebind<T>::other就是这样std::allocator<T>.所以一切正常.