2014-08-29 59 views
3

STL中的所有分配器感知類模板都必須用分配器類型實例化。如果分配器不是模板參數,而是模板模板參數,對用戶來說不是更方便嗎?在分配器感知的STL類中,爲什麼分配器不是模板模板參數?

爲了證明,在std :: vector和std :: basic_string的類模板分別具有以下特徵:

template<class T, class Allocator = std::allocator<T>> class vector; 
template<class CharT, class Traits = std::char_traits<CharT>, class Allocator = std::allocator<CharT>> class basic_string; 

如果我有一個自定義分配器:

template <typename T> 
class MyAllocator 
{ 
    // ... 
}; 

,並希望實例一個使用我的自定義分配器的字符串向量既爲向量分配內部存儲空間,也爲字符串的內部字符數組分配內存,這些事情很快變得尷尬:

typedef std::vector<std::basic_string<char, std::char_traits<char>, MyAllocator<char> >, MyAllocator<std::basic_string<char, std::char_traits<char>, MyAllocator<char>>>> CustomAllocStringVector; 

使用額外的typedef,這可以有所簡化:

typedef std::basic_string<char, std::char_traits<char>, MyAllocator<char>> CustomAllocString; 
typedef std::vector<CustomAllocString, MyAllocator<CustomAllocString>> CustomAllocStringVector; 

但困擾我的是,爲什麼強制用戶顯式指定全型分配器的事情嗎?如果我使用分配器作爲向量char,不應該不用說分配器將是類型分配器< char>?

如果的std :: vector和std :: basic_string的的簽名是:

template<typename T, template <typename ElementType> class AllocatorType = std::allocator> class vector; 
template<typename CharT, typename Traits = std::char_traits<CharT>, template <typename ElementType> class AllocatorType = std::allocator> class basic_string; 

相同的向量型如上可以更簡單地typedef爲:

typedef std::basic_string<char, std::char_traits<char>, MyAllocator> CustomAllocString; 
typedef std::vector<CustomAllocString, MyAllocator> CustomAllocStringVector; 

我的路當然,要求所有的分配器都是模板,但是不會有任何應該可以重複使用的分配器類都不得不滿足這個要求嗎?

我確定有一個很好的理由,但目前我沒有看到它。

+1

其實,即使我是輸入這個問題,另一件事發生在我身上。爲什麼分配器不得不關心它使用的類型?爲什麼客戶端代碼只需要提供對齊方式的x個字節而沒有提及任何類型名稱?這樣,整個問題就會消失。 – antred 2014-08-29 16:23:31

+1

如果您希望將分配器的類型模板化爲包含在容器中的類型(或代替它)之外的某個模板,該怎麼辦? – 2014-08-29 16:26:14

+0

分配器的類型不一定是類模板的專門化。您可以將其限制爲單一類型,這對於特殊用途的分配器可能很有用。 – dyp 2014-08-29 16:26:40

回答

2

這將引入一個要求,即分配器類型只是一個具有一個模板參數的類模板,專用於容器的value_type。您的建議將消除

template<typename T, unsigned int PoolNumber = 0> 
class my_allocator; 

作爲有效的分配器。

與此同時,我可以簡單地使用typedef我已經有我的分配器類型,也不需要把它拆開,或重複它的模板名稱:

template<typename T> class my_allocator; 

typedef my_allocator<int> int_allocator; 

std::list<int, int_allocator> ... // valid currently, difficult to express with your proposal 
+1

'template using pool_3_allocator = my_allocator ;'or ''template struct pool_helper {template using allocator = my_allocator ;};'處理那種具有一些額外的verbage的角落案例我懷疑分配器接口真的很舊,不能改變,更重要。 – Yakk 2014-08-29 20:11:21