只要std :: allocator_traits <t>是专用的,我可以使用任何类T作为分配器类型吗?</t>

时间:2014-07-04 05:16:55

标签: c++ memory-management standards typetraits allocator

根据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);
}

1 个答案:

答案 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_typeallocatedeallocate;在17.6.3.5结尾处有一个示例struct SimpleAllocator,它提供了一个最小的工作接口),或者你想要覆盖默认值(std::allocator_traits设置为使用任何优先于其默认值的已定义成员。)

作为个人问题,我建议通常始终将typedef propagate_on_container_move_assignmentpropagate_on_container_swap(但不是他们的copy_assignment亲戚)从默认的false_type状态覆盖到{ {1}}。由于容器类模板不允许非等效的分配器实例与现有内存相关联(这最终会导致它被错误地解除分配),因此它们必须准备放弃移动语义并重新分配所有内容(相关的一个)提到的两种类型是true_type ,发现分配器实例不相等。可能是编译器足够聪明,可以检测到你的(无状态)分配器类型实例可以从不比较不等,并且处理上面的&#34;做好准备&#34;复杂的死代码。然而,这种死代码处理更易于检测,如果该类型为false_type则更确定会发生,并且还将应用于有状态分配器(允许传播)。换句话说,我认为这两个默认值选择错误。