Follow

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use
Contact

C++ rebind allocator with two template parameter

I’m writing an allocator that takes alignment as a template parameter also the alignment:

template<typename T, std::align_val_t alignment>
class AlignedAllocator {
public:
  using value_type = T;
  using align_type = std::size_t;

  constexpr AlignedAllocator() noexcept = default;
  constexpr AlignedAllocator(const AlignedAllocator&) noexcept = default;
  template<typename U> constexpr AlignedAllocator(const AlignedAllocator<U, alignment>&) noexcept {}

  constexpr std::size_t align() noexcept
  {
    return static_cast<std::size_t>(alignment);
  }

  [[nodiscard]]
  value_type* allocate(std::size_t n)
  {
    return reinterpret_cast<value_type*>(::operator new[](n, alignment));
  }

  void deallocate(value_type* ptr, std::size_t)
  {
    ::operator delete[](ptr, alignment);
  }
};

Problems come when I try to use std::allocator_traits methed rebind since it seems to be able to manage just one parameter, the type T. This makes my allocator non compatible with standard container library:

std::vector<AlignedAllocator<int, std::align_val_t{64}> 

does not compile. A way out would be to add

MEDevel.com: Open-source for Healthcare and Education

Collecting and validating open-source software for healthcare, education, enterprise, development, medical imaging, medical records, and digital pathology.

Visit Medevel

template<typename U> {                                                                                                               
struct rebind {                                                                                                                       
  using other = AlignedAllocator<U, alignment>;                                                                                       
};

this makes the code compile. However the rebind struct is deprecated in c++17 and removed in c++20.

QUESTION

Any suggestion to make my code work without using deprecated features?
One would be to initialize the allocator with the alignment but I would like to keep this parameter in the type.

>Solution :

However the rebind struct is deprecated in c++17 and removed in c++20.

The member rebind of std::allocator is removed because the default works fine for std::allocator. This is irrelevant to your allocator, which needs to provide this struct in order to meet the Allocator requirements.

[allocator.requirements.general]/18, emphasis mine:

If Allocator is a class template instantiation of the form SomeAllocator<T, Args>, where Args is zero or more type arguments, and Allocator does not supply a rebind member template, the standard allocator_traits template uses SomeAllocator<U, Args> in place of Allocator​::​rebind<U>​::​other by default.
For allocator types that are not template instantiations of the above form, no default is provided.

You should provide rebind in your allocator, as expected by std::allocator_traits.

Add a comment

Leave a Reply

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use

Discover more from Dev solutions

Subscribe now to keep reading and get access to the full archive.

Continue reading