All the allocator-aware class templates in the STL have to be instantiated with an allocator type. Wouldn't it be a lot more convenient for users if the allocator wasn't a template argument but a template template argument?
To demonstrate, the std::vector and std::basic_string class templates have the following signatures respectively:
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;
If I have a custom allocator:
template <typename T>
class MyAllocator
{
// ...
};
and want to instantiate a vector of strings that uses my custom allocator both to allocate internal storage for the vector and for the strings' internal character arrays, things quickly become awkward:
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;
Using an additional typedef, this can be simplified somewhat:
typedef std::basic_string<char, std::char_traits<char>, MyAllocator<char>> CustomAllocString;
typedef std::vector<CustomAllocString, MyAllocator<CustomAllocString>> CustomAllocStringVector;
But the thing that bothers me is, why force the user to explicitly specify the full type of the allocator? If I'm using the allocator for a vector of char, shouldn't it go without saying that the allocator is going to be of type allocator< char >?
If the signatures of std::vector and std::basic_string were:
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;
the same vector type as above could be more simply typedef'd as:
typedef std::basic_string<char, std::char_traits<char>, MyAllocator> CustomAllocString;
typedef std::vector<CustomAllocString, MyAllocator> CustomAllocStringVector;
My way, of course, would require that all allocators be templates, but wouldn't any allocator class that is supposed to be the least bit reusable have to meet this requirement anyway?
I'm sure there is a good reason for this, but at the moment I'm not seeing it.
This would introduce a requirement that the allocator type be a class template with exactly one template argument, specialized with the container's value_type
. Your proposal would eliminate
template<typename T, unsigned int PoolNumber = 0>
class my_allocator;
as a valid allocator.
At the same time, I can simply use the typedef
I already have for my allocator type, and don't need to take it apart or repeat its template name:
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