2013-03-05 87 views
10

我試圖爲std::vector<char>使用自定義分配器,但我注意到std::vector不需要/使用我的分配器中的任何成員函數。這怎麼可能?std :: vector <char>的自定義分配器被忽略

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

我正在嘗試使用在線C++ 11編譯器(LiveWorkSpace)提供g ++ 4.7.2,4.8和4.6.3的上述程序。

基本上allocate()deallocate()construct()destroy()未在我的分配器限定,然而程序編譯,所有的元件將被初始化爲0。

回答

14

GCC的標準函數庫可以重新綁定提供的分配器所以在內部它確實是這樣的(在C++ 03):

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

(在C++ 11它採用allocator_traits但在這種情況下,結果是相同的。)

該向量然後在內部存儲該類型的對象並將其用於所有(de)分配。

由於您尚未在分配器中定義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,因爲vector並不嚴格需要重新分配分配器(用戶需要使用allocator<value_type>實例化模板,但GCC的vector無論如何會重新綁定,因此如果用戶實例化vector<int, std::allocator<char>>,它仍然有效。)對於基於節點的容器如std::set您的分配器必須是可以反彈的模板,因爲容器需要分配其內部節點類型,而不是value_type,因此它需要Alloc::rebind<internal_node_type>::other纔有效。

+1

實際上,爲什麼如果用戶提供'std :: allocator '作爲'vector '的分配器,它仍然可以工作?得到編譯器錯誤是否更有意義? – 2013-03-05 13:40:01

+1

我不確定這是否令人滿意,但始終如此。對於其他容器,它更有意義:如果用戶說'std :: map ,std :: allocator >>'儘管可以接受它從技術上來說,分配器必須是'std :: allocator >' – 2013-03-05 13:42:56

+5

@AndyProwl - 分配器實際上應該是模板模板參數,但模板模板參數在當時不存在STL(注意:** STL **,不是**標準庫**)被設計,所以'rebind'被創建。 – 2013-03-05 13:48:54

7

vector將重新綁定分配器。當您將它從std::allocator範圍內調出時,A::rebind<T>::other將僅爲std::allocator<T>。所以一切正常。

相關問題