2009-10-12 21 views
5

私は今STLのソースコードを読んでいます。 私はstl_list.hで読んでいるものを理解していますが、主に以下のスニペットを理解したいと思います(主にテンプレート構文に関連しています)。私たちはラインで_Alloc(1)以下の "テンプレート" を必要とする理由C++テンプレートの構文(STLライブラリのソースコード)に関する質問

テンプレート

class _List_base { 
    ... 
    typedef typename _Alloc::template rebind<_List_node<_Tp> >::other _Node_Alloc_type; //(1). 

    ... 
    typedef _Alloc allocator_type; 
    get_allocator() const 
    { return allocator_type(*static_cast< 
          const _Node_Alloc_type*>(&this->_M_impl)); } // (2) 
    ... 
}; 

は、誰かが説明できますか?

_Node_Alloc_typeを行(2)の_Allocにキャストする理由を説明できる人はいますか?

+3

あなたが見ているSTLの具体的な実装を明確にする必要があります。 STLインターフェイスは標準化されていますが、実装はベンダーごとに異なります。 –

答えて

12

rebindをクラステンプレートとして指定するには、templateキーワードが必要です。それがなければ、rebindは変数または定数(この場合はtypenameキーワードによるタイプ)とみなすことができ、次の<は小なり演算子として解釈できます。

これは、typenameキーワードと多少似ています(タイプとしてotherを特定する必要があります)。

すべてのアロケータは、rebindというメタ機能(つまりクラステンプレート)を提供する必要があります。この関数は、同じアロケータを返しますが、異なるタイプのものです。言い換えれば、

Alloc<U> 

として

Alloc<T>::rebind<U>::other 

名前と同じタイプあなたの質問の2番目の部分は、より多くのコンテキストなしに答えることは困難です。 _M_implの種類は何ですか?そのタイプはどのように定義されていますか?

2

std :: listのgcc実装のようです。その場合には、コンテキストは次のとおりです。

struct _List_impl : public _Node_Alloc_type { ... }; 
_List_impl _M_impl; 

そして、あなたは、メンバ関数の戻り値の型書くのを忘れ:追加する場合は(1)

ため

typedef _Alloc allocator_type; 
allocator_type 
get_allocator() const 
{ return allocator_type(*static_cast<const _Node_Alloc_type*>(&this->_M_impl)); } 

回答ノードがリスト_Tpのリスト内にある場合、実際に割り当てられる必要があるのはオブジェクト_Tpではなく、_Tp(a _List_node<_Tp>)を含むリストノードです。

したがって、std :: listは_List_node<_Tp>を割り当てる必要がありますが、_Tpのアロケータが提供されています。これはテンプレートtypedefの再バインドが便利な点です。タイプUのアロケータをタイプTのアロケータから取得することができます。

この再バインドを使用して、タイプ_Alloc<_Tp>から_Alloc<_List_node<_Tp> >を取得します。(2)コメントとしてソースファイルにするための


回答:

// NOTA BENE 
// The stored instance is not actually of "allocator_type"'s 
// type. Instead we rebind the type to 
// Allocator<List_node<Tp>>, which according to [20.1.5]/4 
// should probably be the same. List_node<Tp> is not the same 
// size as Tp (it's two pointers larger), and specializations on 
// Tp may go unused because List_node<Tp> is being bound 
// instead. 
// 
// We put this to the test in the constructors and in 
// get_allocator, where we use conversions between 
// allocator_type and _Node_Alloc_type. The conversion is 
// required by table 32 in [20.1.5]. 

_AllocのタイプはC++標準の通り_Node_Alloc_typeと同じであると仮定されます。したがって、static_castは変換が合法であると主張します。