Every allocator class must have an interface similar to the following:
template<class T>
class allocator
{
...
template<class Other>
struct rebind { typedef allocator<Other> other; };
};
And classes that use allocators do something redundant like this:
template<class T, class Alloc = std::allocator<T> >
class vector { ... };
But why is this necessary?
In other words, couldn't they have just said:
template<class T>
class allocator { ... };
template<class T, template<class> class Alloc = std::allocator>
class vector { ... };
which is both more elegant, less redundant, and (in some similar situations) potentially safer?
Why did they go the rebind
route, which also causes more redundancy (i.e. you have to say T
twice)?
(Similar question goes to char_traits
and the rest... although they don't all have rebind
, they could still benefit from template template parameters.)
Edit:
But this won't work if you need more than 1 template parameter!
Actually, it works very well!
template<unsigned int PoolSize>
struct pool
{
template<class T>
struct allocator
{
T pool[PoolSize];
...
};
};
Now if vector
was only defined this way:
template<class T, template<class> class Alloc>
class vector { ... };
Then you could just say:
typedef vector<int, pool<1>::allocator> int_vector;
And it would work perfectly well, without needing you to (redundantly) say int
twice.
And a rebind
operation inside vector
would just become Alloc<Other>
instead of Alloc::template rebind<Other>::other
.
std::allocator_traits<SomeAllocator<T, Args...>>::rebind_alloc<U>
isSomeAllocator<U, Args...>
as a sensible default ifSomeAllocator
doesn't providerebind
. – Depositionpool<1>::allocator<char>::rebind<int>::other
need to bepool<4>::allocator<int>
. – Invariableallocator
itself has more than one template parameter which is different from yourpool<1>::allocator
(where the outer instead of inner class has a template parameter). It could work if the additional template (type) parameters have defaults and the user is ok with using the defaults (raising the question why the additional template parameters are present in the first place). Furthermore, template parameters could be types or non-types. It will not work for non-types, which is very inconvenient for the allocator use case (e.g., alignment, padding, etc.). – Aguilar