为什么C ++自定义分配器需要比较运算符?

时间:2017-11-08 18:01:14

标签: c++ c++-standard-library allocator

在实现自定义C ++分配器时,需要定义:

  • operator==用于具有不同value_type
  • 的分配器
  • operator!=用于具有不同value_type
  • 的分配器

您可以在documentation of Allocator concept中看到自定义分配器的示例实现:

#include <cstdlib>
#include <new>
template <class T>
struct Mallocator {
  typedef T value_type;
  Mallocator() = default;
  template <class U> constexpr Mallocator(const Mallocator<U>&) noexcept {}
  T* allocate(std::size_t n) {
    if(n > std::size_t(-1) / sizeof(T)) throw std::bad_alloc();
    if(auto p = static_cast<T*>(std::malloc(n*sizeof(T)))) return p;
    throw std::bad_alloc();
  }
  void deallocate(T* p, std::size_t) noexcept { std::free(p); }
};
template <class T, class U>
bool operator==(const Mallocator<T>&, const Mallocator<U>&) { return true; }
template <class T, class U>
bool operator!=(const Mallocator<T>&, const Mallocator<U>&) { return false; }

问题是这两个运营商的目的是什么?他们什么时候被使用?

修改

请注意我不是要求如何实现这样的运算符(在链接中解释),我问为什么有必要实现它们,所以当使用它们时。

3 个答案:

答案 0 :(得分:8)

了解allocator requirementsoperator==告诉您其中一个分配器对象实例是否可以释放另一个分配器对象实例分配的内存。将一个容器的内容移动到另一个容器时,这一点非常重要。如果第二个容器的分配器是第一个容器的==,你通常可以通过交换一个或两个指针来重复移动,重新使用第一个容器的内存。第二。如果分配器不相等,则复制操作必须复制每个元素,根据需要在第二个容器中分配内存,并释放第一个容器保存的内存。

答案 1 :(得分:1)

您链接的文档包含答案:

  

[operator ==(a1, a2)]仅在由。分配的存储时返回true   可以通过a1取消分配分配器a2。建立反身,   对称和传递关系。不抛出异常。

因此,只要有特定类型的分配器,就可以检查是否可以使用它来释放不同类型的内存,而无需重新绑定分配器。

答案 2 :(得分:-1)

文档也说

  

a1 == a2仅在分配器分配的存储空间时返回true   a1可以通过a2解除分配。建立反身,对称,   和传递关系。不抛出异常。