在分配器感知的STL类中,为什么分配器不是模板模板参数?

问题描述:

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

这将引入一个要求,即分配器类型只是一个具有一个模板参数的类模板,专用于容器的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