2009-10-12 66 views
5

我正在讀取STL源代碼。 雖然我理解stl_list.h中正在閱讀的內容,但我想完全理解下面的代碼片段(主要涉及模板語法,我認爲)。關於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) 
    ... 
}; 

有人能解釋爲什麼我們需要一個 「模板」,在線路(1)以下_Alloc? (並給出這條線的完整解釋?)

有人可以解釋爲什麼我們可以將_Node_Alloc_type投射到_Alloc在行(2)?

+3

你應該說明你在看什麼特定的STL實現。雖然STL接口是標準化的,但實施方式因供應商而異。 – 2009-10-12 19:27:43

回答

12

需要使用template關鍵字將名稱rebind識別爲類模板。沒有它,rebind可以被認爲是一個變量或一個常數(在這種情況下,由於關鍵字typename)和以下<可以被解釋爲一個小於運算符。

這有點類似於typename關鍵字(這當然是識別other作爲一種類型所必需的)。

每個分配器都需要提供一個名爲rebind的元函數(即類模板),該函數返回相同的分配器,但返回不同的類型。換句話說,

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

名稱類型相同

Alloc<U> 

你問題的第二部分是不困難的情況下多來回答。什麼是_M_impl的類型?這種類型是如何定義的?

2

它看起來像std :: list的gcc實現。在這種情況下,上下文是:

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

你忘了寫成員函數的返回類型:

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

答:(1)

當添加節點在_Tp類型的列表中,真正需要分配的不是對象_Tp,而是包含_Tp(a _List_node<_Tp>)的列表節點。

所以std :: list需要能夠分配一個_List_node<_Tp>,但它已經爲_Tp提供了一個分配器。這就是模板typedef rebind派上用場的地方:它可以從類型T的分配器獲得類型U的分配器。

使用此重新綁定,我們從_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的類型是一樣的_Node_Alloc_type按C++標準;因此static_cast聲明轉換是合法的。