Estou escrevendo um alocador que usa o alinhamento como parâmetro de modelo e também o alinhamento:
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);
}
};
Os problemas surgem quando tento usar std::allocator_traits
methed, rebind
pois parece ser capaz de gerenciar apenas um parâmetro, o type T
. Isso torna meu alocador incompatível com a biblioteca de contêineres padrão:
std::vector<AlignedAllocator<int, std::align_val_t{64}>
não compila. Uma saída seria adicionar
template<typename U> {
struct rebind {
using other = AlignedAllocator<U, alignment>;
};
isso faz com que o código seja compilado. No entanto, a rebind
estrutura está obsoleta em c++17 e removida em c++20.
PERGUNTA
Alguma sugestão para fazer meu código funcionar sem usar recursos obsoletos? Uma seria inicializar o alocador com o alinhamento, mas gostaria de manter esse parâmetro no tipo.
O membro
rebind
destd::allocator
é removido porque o padrão funciona bem parastd::allocator
. Isso é irrelevante para o seu alocador, que precisa fornecer essa estrutura para atender aos requisitos do alocador .[allocator.requirements.general]/18 , ênfase minha:
Você deve fornecer
rebind
no seu alocador, conforme esperado pelostd::allocator_traits
.