las - programacion c++ para principiantes
¿Por qué son las funciones de construcción y destrucción de std:: allocator obsoletas en c++ 17? (2)
La especificación c ++ 17 desaprueba la construct
y destroy
miembros del objeto std::allocator
. El grupo de trabajo brindó razones para desaprobar otras funciones de los miembros here , bajo el título "Deprecar los miembros redundantes de std :: allocator".
Sin embargo, no mencionan específicamente por qué esos dos miembros están en desuso o cuál es la recomendación para reemplazar esa funcionalidad. Supongo que la implicación es usar std::allocator_traits::construct
lugar.
Estoy un poco confundido acerca de si la implementación de construct
realidad todavía puede ser necesaria en algunos casos debido a este comentario sobre std::allocator_traits::construct
Debido a que esta función proporciona el repliegue automático a la ubicación nueva, la construcción de función miembro () es un requisito de Allocalizador opcional desde C ++ 11.
Para asignadores personalizados (p. Ej., Para la memoria alineada con la memalign
usa memalign
), ¿volver a colocar nuevamente siempre produce el comportamiento correcto?
La tabla de requisitos del asignador dice que construct(c, args)
, si se proporciona, debe "construir un objeto de tipo C
en c
".
No dice absolutamente nada sobre 1) qué argumentos se deben pasar al constructor de C
o 2) cómo se van a pasar estos argumentos. Esa es la elección del asignador, y de hecho dos asignadores en el estándar se mezclan con los argumentos antes de pasarlos al constructor de C
: std::scoped_allocator_adaptor
y std::pmr::polymorphic_allocator
. Al construir un std::pair
, en particular, los argumentos que pasan al constructor del pair
pueden no parecerse siquiera a los que recibieron.
No hay ningún requisito para reenviar perfectamente, tampoco; una construct(T*, const T&)
estilo C ++ 03 construct(T*, const T&)
está adaptando si es ineficiente.
std::allocator
''s std::allocator
y destroy
están en desuso porque son inútiles: ningún buen código de C ++ 11 y posterior debería llamarlos directamente, y no agregan nada sobre el valor predeterminado.
El manejo de la alineación de memoria debe ser la tarea de allocate
, no de construct
.
Las funciones se eliminaron junto con otras del documento here . Si miramos la sección relevante tenemos
Muchos miembros de std :: allocator duplican redundantemente el comportamiento que de otro modo produce
std::allocator_traits<allocator<T>>
, y se pueden eliminar de forma segura para simplificar esta clase. Además, addressof como función libre sustituye astd::allocator<T>::address
que requiere un objeto asignador del tipo correcto. Finalmente, los alias de tipo de referencia se proporcionaron inicialmente como un medio esperado para la extensión con otros asignadores, pero resultaron no ser útiles cuando se especificaron los requisitos del asignador (17.6.3.5 [allocator.requirements]).Si bien no podemos eliminar estos miembros sin romper la compatibilidad con el código que explícitamente utiliza este tipo de asignador, no deberíamos recomendar su uso continuo. Si un tipo desea admitir asignadores genéricos, debe acceder a la funcionalidad del asignador a través de allocator_traits en lugar de acceder directamente a los miembros del asignador ; de lo contrario, no admitirá adecuadamente los asignadores que dependen de los rasgos para sintetizar los comportamientos predeterminados. De manera similar, si un usuario no tiene la intención de admitir asignadores genéricos, entonces es mucho más simple invocar directamente nuevas, eliminar y asumir las otras propiedades de std :: allocator, como puntero-tipos directamente.
Énfasis mío
Entonces, lo racional fue que no necesitamos duplicar todo el código en el asignador ya que tenemos los rasgos del asignador. Si miramos std::allocator_traits
veremos que sí tiene
allocate
deallocate
construct
destroy
max_size
funciones estáticas para que podamos usar esos en lugar de los que están en el asignador.