每个allocator类必须具有类似于以下内容的接口:
template<class T>
class allocator
{
...
template<class Other>
struct rebind { typedef allocator<Other> other; };
};
Run Code Online (Sandbox Code Playgroud)
使用分配器的类做了多余的事情:
template<class T, class Alloc = std::allocator<T> >
class vector { ... };
Run Code Online (Sandbox Code Playgroud)
但为什么这有必要呢?
换句话说,他们不能只是说:
template<class T>
class allocator { ... };
template<class T, template<class> class Alloc = std::allocator>
class vector { ... };
Run Code Online (Sandbox Code Playgroud)
哪个更优雅,更少冗余,(在某些类似的情况下)可能更安全?
他们为什么要走这rebind条路,这也会造成更多的冗余(即你要说T两次)?
(类似的问题char_traits和其他问题......尽管它们并非都有rebind,但它们仍然可以从模板模板参数中受益.)
但是,如果您需要多于1个模板参数,这将无效!
实际上,它运作得很好!
template<unsigned int PoolSize>
struct pool
{
template<class T>
struct allocator
{
T pool[PoolSize];
... …Run Code Online (Sandbox Code Playgroud) 在技术上有效的是使用不匹配的特化std::allocator(当然,除了它的专业化void)作为STL容器的模板参数(不是全部,但下面列举加上无序_(多)映射/集)?以下代码编译正常.
#include <list>
#include <forward_list>
#include <deque>
#include <set>
#include <map>
int main()
{
struct A { bool operator < (A) const { return true; } };
struct B {};
struct C {};
std::list< A, std::allocator< C > > l;
std::forward_list< A, std::allocator< C > > fl;
std::deque< A, std::allocator< C > > d;
std::set< A, std::less< A >, std::allocator< C > > s;
std::multiset< A, std::less< A >, std::allocator< C > > ms;
std::map< A, …Run Code Online (Sandbox Code Playgroud)