但是我怎麼知道容器使用哪種分配的,如果它 內部從重新綁定模板參數給定的分配?
始終提供一個Allocator<T>
給構造(其中T
是容器的value_type
)。該容器將它轉換爲Allocator<U>
是必要的,其中U
是容器的一些內部數據結構。所述Allocator
需要提供這樣的轉換構造,例如:
template <class T> class allocator {
...
template <class U> allocator(const allocator<U>&);
此外我讀C++ 11現在使用範圍的分配器,其允許 重用容器的分配器爲包含它的容器。
好,更精確地說,C++ 11有一個名爲scoped_allocator_adaptor
的分配器適配器:
template <class OuterAlloc, class... InnerAllocs>
class scoped_allocator_adaptor : public OuterAlloc
{
...
};
從C++ 11:
類模板scoped_allocator_adaptor
是一個分配器模板 ,它指定一個容器使用的內存資源(外部分配器)(與任何其他分配器一樣)並指定一個內部的 分配器資源被傳遞給容器內的每個元素 的構造器。該適配器實例化爲一個外部和零個或多個內部分配器類型。如果只有一個 分配器類型實例化,所述內分配器成爲 scoped_allocator_adaptor
本身,從而使用用於容器相同的分配器 資源和所述容器內的每個元件和,如果 元素本身是CON組tainers,每個它們的元素遞歸地爲 。如果使用多個分配器實例化,則第一個分配器是容器使用的外部分配器,第二個分配器將被傳遞給容器元素的構造函數 ,如果元素本身是容器,則第三個分配器是 傳遞給元素的元素,依此類推。如果將容器嵌套 的深度大於分配器的數量,則最後一個分配器 會在單分配器情況下重複使用,對於任何剩餘的 遞歸。 [注意:scoped_allocator_adaptor
源自 外部分配器類型,所以它可以代替大多數表達式中的外部分配器 類型。 - 注完]
所以,只有當您指定一個scoped_allocator_adaptor
作爲分配器爲您的容器得到作用域分配器行爲。
作用域分配器啓用容器 的實現如何與不知道作用域容器的實現大致不同?
關鍵是容器現在通過一個名爲allocator_traits
的新類來處理它的分配器,而不是直接處理分配器。而容器必須使用allocator_traits
進行某些操作,例如在容器中構建和銷燬value_type
。容器不得直接與分配器通信。
例如,分配器可以提供一種構件稱爲construct
將使用給定的參數在一定的地址構造類型:
template <class T> class Allocator {
...
template<class U, class... Args>
void construct(U* p, Args&&... args);
};
如果分配器不提供此構件,allocator_traits
將提供一個默認實現。在任何情況下,容器必須構建使用所有value_type
s此construct
功能,但使用它通過allocator_traits
,而不是使用allocator
直接:
allocator_traits<allocator_type>::construct(the_allocator, *ugly details*);
的scoped_allocator_adaptor
定製提供construct
功能,這allocator_traits
將轉發到利用uses_allocator
特性並將正確的分配器傳遞給value_type
構造函數。容器仍然對這些細節無知。容器只需知道它必須使用allocator_traits construct
函數構造value_type
。
容器必須處理的更多細節才能正確處理有狀態的分配器。雖然這些細節也通過讓容器不作任何假設來處理,但通過allocator_traits
獲得所有屬性和行爲。該容器甚至不能假定pointer
是T*
。而是通過詢問allocator_traits
發現它是什麼。
簡而言之,要構建一個C++ 11容器,請研究allocator_traits
。然後,當客戶使用scoped_allocator_adaptor
時,您可以免費獲得有限範圍的分配器行爲。