根据http://en.cppreference.com/w/cpp/concept/Allocator,可以用作分配器类型的一个类必须满足许多要求。但是,我找不到C ++标准规定的相同要求。标准只要求分配器类型不能是非类型。 (见n3797 20.7.8.1)
如果我有一个空的课程Alloc
和一个完全专业的std::allocator_traits<Alloc>
,我可以使用Alloc
,如下所示:
#include <vector>
struct Alloc {};
template<>
std::allocator_traits<Alloc>
{
// full of definitions as per the requirements for std::allocator_traits<T>
};
int main()
{
std::vector<int, Alloc> coll;
coll.push_back(8);
}
答案 0 :(得分:1)
只要您打算将分配器与STL容器(或符合相同约定的代码)一起使用,您就可以通过为您的类专门设置std::allocator_traits
来定义您的分配器(为此它只需要定义;考虑它,我认为你甚至可能为此目的劫持现有的非分配器类),因为调用你的分配器不会直接进行,而是通过std::allocator_traits
专门化。
这样做似乎打败了那个类模板的目的但是,因为通过定义那个specilisation你正在丢失模板已经放置的所有默认值,所以你必须重新定义所有东西,这不比定义所有内容更容易你的Alloc
课直接。具体来说,17.6.4.2.1似乎使其成为未定义的行为,只是专门化个别成员函数,如std::allocator_traits<Alloc>::allocate
,当然必须定义。
预期用途显然不完全是std::allocator_traits
,而只是定义Alloc
未提供默认值的成员(主要是value_type
,allocate
和deallocate
;在17.6.3.5结尾处有一个示例struct SimpleAllocator
,它提供了一个最小的工作接口),或者你想要覆盖默认值(std::allocator_traits
设置为使用任何优先于其默认值的已定义成员。)
作为个人问题,我建议通常始终将typedef propagate_on_container_move_assignment
和propagate_on_container_swap
(但不是他们的copy_assignment
亲戚)从默认的false_type
状态覆盖到{ {1}}。由于容器类模板不允许非等效的分配器实例与现有内存相关联(这最终会导致它被错误地解除分配),因此它们必须准备放弃移动语义并重新分配所有内容(相关的一个)提到的两种类型是true_type
和,发现分配器实例不相等。可能是编译器足够聪明,可以检测到你的(无状态)分配器类型实例可以从不比较不等,并且处理上面的&#34;做好准备&#34;复杂的死代码。然而,这种死代码处理更易于检测,如果该类型为false_type
则更确定会发生,并且还将应用于有状态分配器(允许传播)。换句话说,我认为这两个默认值选择错误。