Aquí está la documentación sobre cppreference , aquí está el borrador de trabajo.
Debo admitir que no entendí cuál es el propósito real polymorphic_allocator
y cuándo / por qué / cómo debería usarlo.
Como ejemplo, pmr::vector
tiene la siguiente firma:
namespace pmr {
template <class T>
using vector = std::vector<T, polymorphic_allocator<T>>;
}
¿Qué ofrece la polymorphic_allocator
oferta? ¿Qué std::pmr::vector
ofrece también en lo que respecta a los anticuados std::vector
? ¿Qué puedo hacer ahora que no pude hacer hasta ahora?
¿Cuál es el propósito real de ese asignador y cuándo debería usarlo realmente?
allocator<T>
inherentemente tiene. Por lo tanto, verá valor en él si usa asignadores con frecuencia.Respuestas:
Cita de elección de cppreference:
El problema con los asignadores "regulares" es que cambian el tipo de contenedor. Si desea una
vector
con un asignador específico, puede hacer uso delAllocator
parámetro de plantilla:El problema ahora es que este vector no es del mismo tipo que un vector con un asignador diferente. No puede pasarlo a una función que requiera un vector de asignador predeterminado, por ejemplo, o asignar dos vectores con un tipo de asignador diferente a la misma variable / puntero, por ejemplo:
Un asignador polimórfico es un tipo de asignador único con un miembro que puede definir el comportamiento del asignador a través del envío dinámico en lugar de a través del mecanismo de plantilla. Esto le permite tener contenedores que utilizan una asignación específica y personalizada, pero que aún son de un tipo común.
La personalización del comportamiento del asignador se realiza dándole al asignador un
std::memory_resource *
:El principal problema restante, a mi modo de ver, es que un
std::pmr::
contenedor todavía no es compatible con elstd::
contenedor equivalente que usa el asignador predeterminado. Necesita tomar algunas decisiones al momento de diseñar una interfaz que funcione con un contenedor:Una solución de plantilla permite cualquier asignador, incluido un asignador polimórfico, pero tiene otros inconvenientes (tamaño del código generado, tiempo de compilación, el código debe exponerse en el archivo de encabezado, potencial para una mayor "contaminación de tipo" que sigue empujando el problema hacia afuera). Una solución de asignador polimórfico, por otro lado, dicta que se debe utilizar un asignador polimórfico . Esto excluye el uso de
std::
contenedores que usan el asignador predeterminado y podría tener implicaciones para interactuar con el código heredado.En comparación con un asignador normal, un asignador polimórfico tiene algunos costos menores, como la sobrecarga de almacenamiento del puntero memory_resource (que probablemente sea insignificante) y el costo del envío de funciones virtuales para asignaciones. El principal problema, en realidad, es probablemente la falta de compatibilidad con el código heredado que no usa asignadores polimórficos.
fuente
std::pmr::
muy probable que el diseño binario de las clases sea diferente?reinterpret_cast
entre unstd::vector<X>
ystd::pmr::vector<X>
, si eso es lo que estás preguntando.std::pmr::
contenedor todavía no es compatible con elstd::
contenedor equivalente que usa el asignador predeterminado" . Tampoco hay un operador de asignación definido de uno a otro. En caso de duda, pruébelo: godbolt.org/z/Q5BKev (el código no es exactamente como el anterior porque gcc / clang tienen las clases de asignación polimórfica en un espacio de nombres "experimental").template<class OtherA, std::enable_if< A can be constructed from OtherA > vector( vector<T, OtherA>&& )
constructor. No estaba seguro y no sabía dónde encontrar un compilador que tuviera pmr compatible con TS.polymorphic_allocator
es a un asignador personalizado comostd::function
a una llamada de función directa.Simplemente le permite usar un asignador con su contenedor sin tener que decidir, en el punto de declaración, cuál. Entonces, si tiene una situación en la que sería apropiado más de un asignador, puede usar
polymorphic_allocator
.Tal vez desee ocultar qué asignador se usa para simplificar su interfaz, o tal vez desee poder cambiarlo por diferentes casos de tiempo de ejecución.
Primero necesita un código que necesita un asignador, luego necesita poder intercambiar cuál se usa, antes de considerar el vector pmr.
fuente
Un inconveniente de los asignadores polimórficos es que
polymorphic_allocator<T>::pointer
siempre es justoT*
. Eso significa que no puede usarlos con punteros elegantes . Si desea hacer algo como colocar elementos de avector
en la memoria compartida y acceder a ellos a través deboost::interprocess::offset_ptr
s , debe usar un asignador no polimórfico antiguo normal para eso.Por lo tanto, aunque los asignadores polimórficos le permiten variar el comportamiento de asignación sin cambiar el tipo estático de un contenedor, limitan lo que es una asignación .
fuente