Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why C++ custom allocator needs comparison operators?

While implementing custom C++ allocator, one needs to define:

  • operator== for the allocator with different value_type
  • operator!= for the allocator with different value_type

You can see the example implementation of custom allocator in 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; }

The question is what are purposes of those 2 operators? When are they being used?

EDIT:

Please note I am not asking how to implement such operators (explained in the link), I am asking why it is necessary to implement them, so when those are being used.

like image 216
Mariusz Jaskółka Avatar asked Nov 08 '17 18:11

Mariusz Jaskółka


People also ask

What type of C operator Do you need to compare two values?

The equality operator (==) is used to compare two values or expressions.

How does STD allocator work?

std::allocator calls/uses new and delete . It is simply another level in the C++ memory hierarchy, used to serve the various needs of the C++ standard library, particularly the containers, but other types too. The C++ library containers use the allocator to automatically manage the memory of the contained elements.

What is a custom allocator?

Allocators handle all the requests for allocation and deallocation of memory for a given container. The C++ Standard Library provides general-purpose allocators that are used by default, however, custom allocators may also be supplied by the programmer.


2 Answers

Read about the allocator requirements. operator== tells you whether one of the allocator object instances can free memory that was allocated by the other. That's important when you move the contents of one container into another. If the second container's allocator is == to the first container's, you can, in general, do the move by swapping a pointer or two, reusing the first container's memory in the second. If the allocators are not equal, then the copy operation has to copy each element, allocating memory in the second container as needed, and free the memory held by the first container.

like image 173
Pete Becker Avatar answered Oct 13 '22 08:10

Pete Becker


The very documentation you linked to contains the answer:

[operator ==(a1, a2)] returns true only if the storage allocated by the allocator a1 can be deallocated through a2. Establishes reflexive, symmetric, and transitive relationship. Does not throw exceptions.

So whenever you have an allocator for a certain type, you can check whether you can use it to deallocate memory of a different type without the need to rebind the allocator.

like image 44
Jodocus Avatar answered Oct 13 '22 08:10

Jodocus