Home > Software design >  Should pmr containers with different allocators compare equal?
Should pmr containers with different allocators compare equal?

Time:12-18

Say I have a container that uses a hardcoded pmr allocator to store data. What is the consensus among the C community: should operator==() compare equal on objects that only differ by their allocator or should it be strongly ordered? I can see arguments for both cases.

Possible implementation of a container:

Demo

#include <cstdio>
#include <memory_resource>
#include <array>

struct alloc_aware_ctr
{
    using allocator_type = std::pmr::polymorphic_allocator<std::byte>;
    auto get_allocator() {
        return allocator_;
    }

    alloc_aware_ctr(allocator_type allocator = {})
        :   allocator_{allocator}
    {

    }

    auto operator==(const alloc_aware_ctr& other) {
        return allocator_ == other.allocator_;
    }

    allocator_type allocator_;
};

int main()
{

    std::array<std::byte, 10> buffer;

    std::pmr::monotonic_buffer_resource mbr{buffer.data(), buffer.size(), std::pmr::null_memory_resource() };
    std::pmr::polymorphic_allocator<std::byte> pa{&mbr};

    alloc_aware_ctr a;
    alloc_aware_ctr b{pa};

    if (a == b) {
        printf("They are the same!\n");
    }

}

This one distinguishes the allocators ^^

CodePudding user response:

I can't think of a reason that the allocator should matter. == should compare the values of the elements of the container for equality. How the values are stored shouldn't matter. The allocators comparing equal is only relevant to deciding whether one can be used to deallocate storage allocated by the other. Some allocator types may never compare equal.

This is also what the Container requirement in the standard library requires.

However, if the type of the allocator was different, then typically the resulting containers are not comparable at all. But I would still say that if they are comparable, they should not compare unequal just because of the allocator.

CodePudding user response:

The standard defines a set of requirements for containers, and additional requirements for allocator-aware containers. The container requirements specify the behavior of operator== and operator<=> for two instances of containers of the same type (ie: same template parameters). This is not in the section for allocator-aware containers, and nothing in that section changes its behavior.

The behavior for operator== is that it's equivalent to using std::equal on their iterators. The behavior of operator<=>, if T itself provides ordering, is equivalent to std::lexicographical_­compare_­three_­way. Neither function cares about the allocator's value.

Therefore, comparisons between PMR-containers (as defined by the standard library's rules) are required to work and are required to ignore the actual memory_resources that they use.

  • Related