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

标签 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);
}

最佳答案

只要您打算将分配器与 STL 容器(或遵循相同约定的代码)一起使用,您就可以通过专门为您的类定义 std::allocator_traits 来定义您的分配器(然后只需定义它就足够了; 考虑到这一点,我认为您甚至可能为此目的劫持现有的非分配器类),因为不会直接调用您的分配器,而是通过 std::allocator_traits 特化。

但是,这样做似乎违背了该类模板的目的,因为通过定义该规范,您将失去模板已设置的所有默认值,因此您必须重新定义所有内容,这并不比在你的Alloc直接上课。具体来说,17.6.4.2.1 似乎使其成为未定义的行为,仅专门化单个成员函数,如 std::allocator_traits<Alloc>::allocate,当然必须对其进行定义。

预期用途显然是根本不专门化 std::allocator_traits,而只是定义没有提供默认值的 Alloc 成员(本质上是 value_typeallocatedeallocate ;在末尾17.6.3.5 有一个示例结构 SimpleAllocator 提供了一个最小的工作接口(interface)),或者您想要覆盖默认值( std::allocator_traits 设置为使用任何定义的成员优先于其默认值)。

作为个人问题,我建议通常总是将 typedefs propagate_on_container_move_assignmentpropagate_on_container_swap(但不是他们的 copy_assignment 亲戚)从默认状态 false_type 覆盖为 true_type 。由于容器类模板不允许非等效分配器实例与现有内存相关联(这最终会导致它被错误地释放),因此它们必须准备好放弃移动语义并重新分配所有内容,以防(相关的)两个提到的类型是 false_type 分配器实例被发现是不相等的。编译器可能足够聪明,可以检测到您的(无状态)分配器类型实例永远不会比较不相等,并将上述“准备好”的复杂情况视为死代码。然而,如果该类型是 true_type ,这种死代码处理更容易检测并且更确定发生,然后还将申请有状态分配器(允许传播)。换句话说,我认为这两个默认值只是选择错误。

关于c++ - 只要 std::allocator_traits<T> 是专门的,我可以使用任何类 T 作为分配器类型吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24567133/

相关文章:

ios - 自包含 UIView 子类中的 UITapGestureRecognizer EXC_BAD_ACCESS

c++ - glibc 上的 valgrind 输出在 C++ 中检测到错误

c++ - 创建字符串到函数 vector 的 HashMap

c++ - OpenCV 上 SIFT 描述符的正确输出类型是什么?

c++ - 编译器如何在结构中完成内存分配?

c++ - 打印非常大的 float

c++ - 在 C++ 中, "const_iterator"与 "const iterator"相同吗?

c++ - 为什么这个简单的循环不起作用?

c++ - 链接器在 Windows 上的 qtcreator 中忽略/openmp

c++ - 我可以在 C++ 标准的哪个位置读取整型文字的类型?