为什么 C++ 自定义分配器需要比较运算符?
Why C++ custom allocator needs comparison operators?
在实现自定义 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; }
问题是这两个运算符的目的是什么?它们什么时候使用?
编辑:
请注意我不是在问如何实现这样的运算符(在link中有解释),我是在问为什么有必要实现它们,所以当那些正在使用中。
您链接到的文档包含答案:
[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.
因此,无论何时您拥有某种类型的分配器,您都可以检查是否可以使用它来释放不同类型的内存,而无需重新绑定分配器。
文档还说
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.
了解 allocator requirements。 operator==
告诉您一个分配器对象实例是否可以释放另一个分配的内存。当您将一个容器的内容物移动到另一个容器时,这一点很重要。如果第二个容器的分配器是 ==
到第一个容器的,您通常可以通过交换一个或两个指针来移动,在第二个容器中重用第一个容器的内存。如果分配器不相等,则复制操作必须复制每个元素,根据需要在第二个容器中分配内存,并释放第一个容器持有的内存。
在实现自定义 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; }
问题是这两个运算符的目的是什么?它们什么时候使用?
编辑:
请注意我不是在问如何实现这样的运算符(在link中有解释),我是在问为什么有必要实现它们,所以当那些正在使用中。
您链接到的文档包含答案:
[
operator ==(a1, a2)
] returns true only if the storage allocated by the allocatora1
can be deallocated througha2
. Establishes reflexive, symmetric, and transitive relationship. Does not throw exceptions.
因此,无论何时您拥有某种类型的分配器,您都可以检查是否可以使用它来释放不同类型的内存,而无需重新绑定分配器。
文档还说
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.
了解 allocator requirements。 operator==
告诉您一个分配器对象实例是否可以释放另一个分配的内存。当您将一个容器的内容物移动到另一个容器时,这一点很重要。如果第二个容器的分配器是 ==
到第一个容器的,您通常可以通过交换一个或两个指针来移动,在第二个容器中重用第一个容器的内存。如果分配器不相等,则复制操作必须复制每个元素,根据需要在第二个容器中分配内存,并释放第一个容器持有的内存。