为什么许多Allocator功能是可选的?

时间:2016-09-09 06:20:33

标签: c++ memory-management stl allocator

我刚刚完成了一个覆盖operator new和delete的个人项目,并开始了解该过程中的allocator类。阅读了几个在线参考资料,包括cppreference.com,我注意到很多功能被描述为可选。

我的问题是分配器接收者如何,例如std::set,如果接收到的分配器只选择实现函数和类型,则工作吗?

我理解是否需要从一些具有所有函数的默认实现的基类派生分配器,但似乎没有分配器的继承要求。

或者是由于编译错误而需要提醒实现这些可选功能的原因?

作为参考,这是我第一次尝试使用分配器作为std::set的第三个模板参数。我研究了一个现有的例子,所以我相信我所实现的大部分内容可能都是不必要的,但我还不知道如果我将来选择使用带有其他STL容器的分配器,如何判断将是必要的。除非,期望是基于编译错误来解决这个问题......?

template <typename T>
class Allocator // Custom allocator for use by AllocSet::mAllocatedPtrs to avoid infinite recursion
{               // (because inserting an element in std::set calls ::operator new, which is overridden to add to AllocSet::mAllocatedPtrs).
    public:
        typedef T value_type;
        typedef T* pointer;
        typedef T& reference;
        typedef const T* const_pointer;
        typedef const T& const_reference;
        typedef size_t size_type;
        typedef ptrdiff_t difference_type;

        template <typename U>
        struct rebind { typedef Allocator<U> other; };

        Allocator() { }
        template <typename U> Allocator(const Allocator<U>&) { }
        virtual ~Allocator() { }

        pointer allocate(size_t numT) { return (T*)(malloc(numT * sizeof(T))); }
        void deallocate(pointer p, size_type st) { free(p); }

        size_type max_size() { return size_type(-1); }

        reference operator=(const_reference) { return *this; }
        template <typename U> reference operator=(const Allocator<U>&) { return *this; }
        template <typename U> bool operator==(const Allocator<U>&) { return true; }
        template <typename U> bool operator!=(const Allocator<U>&) { return false; }

        pointer address(reference r) { return &r; }
        const_pointer address(const_reference r) { return &r; }
};

1 个答案:

答案 0 :(得分:4)

  

我的问题是分配器接收者如何,例如std :: set,如果它的接收分配器只选择实现函数和类型吗?

如果你看the allocator concecpt

  

一些需求是可选的:模板std :: allocator_traits提供所有可选需求的默认实现,所有标准库容器和其他分配器识别类通过std :: allocator_traits访问分配器,而不是直接访问。

这也是为什么这么多东西是可选的 - 大多数分配器实现真的没有必要改变它们,所以为什么要这么麻烦?假设您对新的内存重组算法有所了解,为什么需要定义pointer

  

或者是由于编译错误而需要提醒实现这些可选功能的原因?

不,分配器的概念是well defined。它指定您提供提供的内容,以及您可以提供的内容。没有必要依赖编译错误。

您可以在the standard,$ 17.6.3.5。

中找到要求