每个分配器类必须具有类似以下接口的接口:
但这为什么是必要的呢?
换句话说,他们不可以只说:
他们为什么选择了导致更多冗余的“重新绑定”(即您必须两次使用T)的路线,而不是更优雅、不那么冗余,在某些类似情况下可能更安全的方案?(类似的问题也适用于char_traits和其他情况…尽管它们并非都有“重新绑定”,但它们仍然可以从模板模板参数中受益。)
编辑:
“但是,如果你需要超过1个模板参数,这种方法将行不通!”
实际上,这种方法非常有效!
现在,如果
那么你可以直接说:
template<class T>
class allocator
{
...
template<class Other>
struct rebind { typedef allocator<Other> other; };
};
使用分配器的类会做一些冗余的操作,例如:
template<class T, class Alloc = std::allocator<T> >
class vector { ... };
但这为什么是必要的呢?
换句话说,他们不可以只说:
template<class T>
class allocator { ... };
template<class T, template<class> class Alloc = std::allocator>
class vector { ... };
他们为什么选择了导致更多冗余的“重新绑定”(即您必须两次使用T)的路线,而不是更优雅、不那么冗余,在某些类似情况下可能更安全的方案?(类似的问题也适用于char_traits和其他情况…尽管它们并非都有“重新绑定”,但它们仍然可以从模板模板参数中受益。)
编辑:
“但是,如果你需要超过1个模板参数,这种方法将行不通!”
实际上,这种方法非常有效!
template<unsigned int PoolSize>
struct pool
{
template<class T>
struct allocator
{
T pool[PoolSize];
...
};
};
现在,如果
vector
只是这样定义的:template<class T, template<class> class Alloc>
class vector { ... };
那么你可以直接说:
typedef vector<int, pool<1>::allocator> int_vector;
即使不需要您重复两次输入 int
,它也可以完美地工作。
vector
中的 rebind
操作只需变为 Alloc<Other>
,而不是 Alloc::template rebind<Other>::other
。
SomeAllocator
没有提供rebind
,则std::allocator_traits<SomeAllocator<T, Args...>>::rebind_alloc<U>
默认为SomeAllocator<U, Args...>
。这是一个合理的默认值。 - Luc Dantonpool<1>::allocator<char>::rebind<int>::other
更改为pool<4>::allocator<int>
。 - Jarod42allocator
本身具有多个模板参数且与您的pool<1>::allocator
(_其中外部而不是内部类具有模板参数_)不同时,它将无法工作。如果附加的模板(类型)参数具有默认值并且用户使用默认值,则可以工作(_这引发了为什么首先存在附加的模板参数的问题_)。此外,模板参数可以是类型或非类型。对于非类型,它将无法工作,这对于分配器用例非常不方便(_例如,对齐、填充等_)。 - Matthias