Aqui está a documentação sobre cppreference , aqui está o esboço de trabalho.
Devo admitir que não entendi qual é o verdadeiro propósito polymorphic_allocator
e quando / por que / como devo usá-lo.
Como exemplo, o pmr::vector
tem a seguinte assinatura:
namespace pmr {
template <class T>
using vector = std::vector<T, polymorphic_allocator<T>>;
}
O que a polymorphic_allocator
oferta? O que a std::pmr::vector
oferta também oferece em relação aos antiquados std::vector
? O que posso fazer agora que não fui capaz de fazer até agora?
Qual é o propósito real desse alocador e quando devo usá-lo de fato?
allocator<T>
inerentemente. Portanto, você verá valor nisso se usar alocadores com frequência.Respostas:
Citação de escolha de cppreference:
O problema com os alocadores "regulares" é que eles mudam o tipo do contêiner. Se você quiser um
vector
com um alocador específico, pode usar oAllocator
parâmetro do modelo:O problema agora é que esse vetor não é do mesmo tipo que um vetor com um alocador diferente. Você não pode passá-lo para uma função que requer um vetor alocador padrão, por exemplo, ou atribuir dois vetores com um tipo de alocador diferente para a mesma variável / ponteiro, por exemplo:
Um alocador polimórfico é um único tipo de alocador com um membro que pode definir o comportamento do alocador por meio de despacho dinâmico em vez de por meio do mecanismo de modelo. Isso permite que você tenha contêineres que usam alocação específica e personalizada, mas que ainda são de um tipo comum.
A personalização do comportamento do alocador é feita dando ao alocador um
std::memory_resource *
:O principal problema remanescente, a meu ver, é que um
std::pmr::
contêiner ainda não é compatível com ostd::
contêiner equivalente que usa o alocador padrão. Você precisa tomar algumas decisões no momento de projetar uma interface que funcione com um contêiner:Uma solução de modelo permite qualquer alocador, incluindo um alocador polimórfico, mas tem outras desvantagens (tamanho do código gerado, tempo de compilação, o código deve ser exposto no arquivo de cabeçalho, potencial para mais "contaminação de tipo" que continua empurrando o problema para fora). Uma solução de alocador polimórfico, por outro lado, determina que um alocador polimórfico deve ser usado. Isso impede o uso de
std::
contêineres que usam o alocador padrão e pode ter implicações para a interface com o código legado.Comparado a um alocador regular, um alocador polimórfico tem alguns custos menores, como a sobrecarga de armazenamento do ponteiro memory_resource (que é provavelmente insignificante) e o custo de despacho de função virtual para alocações. O principal problema, realmente, é provavelmente a falta de compatibilidade com o código legado que não usa alocadores polimórficos.
fonte
std::pmr::
provável que o layout binário para classes seja diferente?reinterpret_cast
entre umstd::vector<X>
estd::pmr::vector<X>
, se é isso que você está perguntando.std::pmr::
contêiner ainda não é compatível com ostd::
contêiner equivalente usando o alocador padrão" . Também não há operador de atribuição definido de um para o outro. Em caso de dúvida, experimente: godbolt.org/z/Q5BKev (o código não é exatamente como o anterior porque gcc / clang tem as classes de alocação polimórfica em um namespace "experimental").template<class OtherA, std::enable_if< A can be constructed from OtherA > vector( vector<T, OtherA>&& )
construtor. Eu não tinha certeza e não sabia onde encontrar um compilador que tivesse PMR compatível com TS.polymorphic_allocator
é para um alocador personalizado assim comostd::function
para uma chamada de função direta.Ele simplesmente permite que você use um alocador com seu contêiner sem ter que decidir, no ponto de declaração, qual deles. Portanto, se você tiver uma situação em que mais de um alocador seja apropriado, você pode usar
polymorphic_allocator
.Talvez você queira ocultar qual alocador é usado para simplificar sua interface, ou talvez queira trocá-lo por diferentes casos de tempo de execução.
Primeiro você precisa de um código que precisa de um alocador, então você precisa ser capaz de trocar qual deles é usado, antes de considerar o vetor pmr.
fonte
Uma desvantagem dos alocadores polimórficos é que eles
polymorphic_allocator<T>::pointer
são sempre justosT*
. Isso significa que você não pode usá-los com dicas sofisticadas . Se você quiser fazer algo como colocar elementos de avector
na memória compartilhada e acessá-los por meio deboost::interprocess::offset_ptr
s , você precisa usar um alocador não polimórfico antigo regular para isso.Portanto, embora os alocadores polimórficos permitam variar a alocação comportamento da sem alterar o tipo estático de um contêiner, eles limitam o que é uma alocação .
fonte