La spécification c ++ 17 déprécie les membres construct
et destroy
des std::allocator
objet. Le groupe de travail a fourni la justification de la dépréciation d'autres fonctions membres ici , sous le titre "Déprécier les membres redondants de std :: allocator".
Cependant, ils ne mentionnent pas spécifiquement pourquoi ces deux membres sont déconseillés ou quelle est la recommandation pour remplacer cette fonctionnalité. Je suppose que l'implication est d'utiliser std::allocator_traits::construct
au lieu.
Je suis un peu confus quant à savoir si l'implémentation de construct
peut en fait être encore nécessaire dans certains cas à cause de ce commentaire sur std::allocator_traits::construct
Étant donné que cette fonction fournit le retour automatique au placement new, la fonction membre construct () est une exigence d'allocateur facultative depuis C++ 11.
Pour les allocateurs personnalisés (par exemple pour la mémoire alignée sur une page utilisant memalign
), le retour au placement new
produira-t-il toujours le comportement correct?
Le table des exigences d'allocateur indique que construct(c, args)
, s'il est fourni, doit "construire un objet de type C
à c
".
Il ne dit absolument rien 1) quels arguments doivent être passés au constructeur de C
ou 2) comment ces arguments doivent être passés. C'est le choix de l'allocateur, et en fait, deux allocateurs de la norme jouent avec les arguments avant de les passer au constructeur de C
: std::scoped_allocator_adaptor
et std::pmr::polymorphic_allocator
. Lors de la construction d'un std::pair
, En particulier, les arguments qu'ils transmettent au constructeur de pair
peuvent même ne pas ressembler à ceux qu'ils ont reçus.
Il n'y a pas non plus d'obligation de transmettre parfaitement; une construct(T*, const T&)
de style C++ 03 est conforme si elle est inefficace.
std::allocator
construct
et destroy
sont déconseillés car ils sont inutiles: aucun bon code C++ 11 et ultérieur ne devrait les appeler directement, et ils n'ajoutent rien par rapport à la valeur par défaut .
La gestion de l'alignement de la mémoire devrait être la tâche de allocate
, pas de construct
.
Les fonctions ont été supprimées avec d'autres du papier D0174R0 Déprécier les parties de la bibliothèque résiduelle en C++ 17 . Si nous regardons la section pertinente, nous avons
De nombreux membres de std :: allocator dupliquent de manière redondante un comportement qui est sinon produit par
std::allocator_traits<allocator<T>>
, et pourrait être supprimé en toute sécurité pour simplifier cette classe. De plus, addressof en tant que fonction libre remplacestd::allocator<T>::address
qui nécessite un objet allocateur du bon type. Enfin, les alias de type de référence ont été initialement fournis comme un moyen prévu d'extension avec d'autres allocateurs, mais se sont avérés ne pas servir un objectif utile lorsque nous avons spécifié les exigences d'allocateur (17.6.3.5 [allocator.requirements]).Bien que nous ne puissions pas supprimer ces membres sans rompre la compatibilité descendante avec le code qui utilisait explicitement ce type d'allocateur, nous ne devrions pas recommander leur utilisation continue. Si un type souhaite prendre en charge les allocateurs génériques, il doit accéder aux fonctionnalités de l'allocateur via allocator_traits plutôt que d'accéder directement aux membres de l'allocateur - sinon il ne prendra pas correctement en charge les allocateurs qui s'appuient sur les traits pour synthétiser la valeur par défaut. comportements. De même, si un utilisateur n'a pas l'intention de prendre en charge les allocateurs génériques, il est beaucoup plus simple d'appeler directement new, delete et d'assumer directement les autres propriétés de std :: allocator telles que les types de pointeurs.
Emphase mine
Donc, le rationnel était que nous n'avons pas besoin de dupliquer tout le code dans l'allocateur puisque nous avons les traits d'allocateur. Si nous regardons std::allocator_traits
nous verrons qu'il a
allocate
deallocate
construct
destroy
max_size
fonctions statiques afin que nous puissions les utiliser au lieu de celles de l'allocateur.