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
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.
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.
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 formSomeAllocator<T, Args>
, whereArgs
is zero or more type arguments, andAllocator
does not supply a rebind member template, the standardallocator_traits
template usesSomeAllocator<U, Args>
in place ofAllocator::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
.