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?
}

g++ 4.7.2、4.8、および 4.6.3 を提供するオンライン C++11 コンパイラ (LiveWorkSpace) で上記のプログラムを試していました。

基本的allocate()に 、deallocate()construct()およびdestroy()はアロケーターで定義されていませんが、プログラムがコンパイルされ、すべての要素が 0 に初期化されます。

4

2 に答える 2

14

GCC 標準ライブラリは、提供されたアロケータを常に再バインドするため、内部的に次のような処理を行います (C++03 の場合):

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

(C++11 では使用しますallocator_traitsが、この場合、結果は同じです。)

次に、ベクターはその型のオブジェクトを内部に格納し、すべての割り当て (解放) に使用します。

アロケーターでメンバー テンプレートを定義していないため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;
      };

注意: アロケータを厳密に再バインドする必要がないためvector、これは でのみ機能します (ユーザーは でテンプレートをインスタンス化する必要がありますが、ユーザーがインスタンス化しても機能するようにGCCは再バインドします)。アロケータなどのノードベースのコンテナの場合コンテナは ではなく内部ノード タイプを割り当てる必要があるため、再バインド可能なテンプレートである必要があります。そのため、有効である必要があります。vectorallocator<value_type>vectorvector<int, std::allocator<char>>std::setvalue_typeAlloc::rebind<internal_node_type>::other

于 2013-03-05T13:36:16.360 に答える
7

vectorアロケータを再バインドします。からスコープに入れるとstd::allocatorA::rebind<T>::other単純にになりますstd::allocator<T>。したがって、すべてが正常に機能します。

于 2013-03-05T13:28:36.990 に答える