C++ named requirements: AllocatorAwareContainer (since C++11)
Un AllocatorAwareContainer est un Container qui contient une instance d'un Allocator et utilise cette instance dans toutes ses fonctions membres pour allouer et désallouer la mémoire ainsi que pour construire et détruire les objets dans cette mémoire (ces objets peuvent être des éléments du conteneur, des nœuds ou, pour les conteneurs non ordonnés, des tableaux de compartiments) , sauf que les spécialisations de std::basic_string n'utilisent pas les allocateurs pour la construction/destruction de leurs éléments (depuis C++23) .
Les règles suivantes s'appliquent à la construction de conteneurs :
- Les constructeurs de copie des AllocatorAwareContainer s obtiennent leurs instances de l'allocateur en appelant std:: allocator_traits < allocator_type > :: select_on_container_copy_construction sur l'allocateur du conteneur copié.
- Les constructeurs de déplacement obtiennent leurs instances d'allocateurs par construction par déplacement à partir de l'allocateur appartenant à l'ancien conteneur.
- Tous les autres constructeurs prennent un paramètre const allocator_type & .
La seule façon de remplacer un allocateur est l'affectation par copie, l'affectation par déplacement et l'échange :
- La copie par affectation remplacera l'allocateur seulement si std:: allocator_traits < allocator_type > :: propagate_on_container_copy_assignment :: value est true .
- Le déplacement par affectation remplacera l'allocateur seulement si std:: allocator_traits < allocator_type > :: propagate_on_container_move_assignment :: value est true .
- L'échange remplacera l'allocateur seulement si std:: allocator_traits < allocator_type > :: propagate_on_container_swap :: value est true . Plus précisément, il échangera les instances d'allocateur via un appel non qualifié à la fonction non-membre swap, voir Swappable . Si l'échange ne propage pas l'allocateur, échanger deux conteneurs avec des allocateurs inégaux est un comportement indéfini.
-
L'accesseur
get_allocator()obtient une copie de l'allocateur qui a été utilisé pour construire le conteneur ou installé par l'opération de remplacement d'allocateur la plus récente.
La seule exception est std:: basic_string < CharT,Traits,Allocator > :: assign , qui peut également propager l'allocateur.
Table des matières |
Exigences
Un type satisfait AllocatorAwareContainer s'il satisfait Container et, étant donnés les types et valeurs suivants, les exigences sémantiques et de complexité dans les tableaux ci-dessous sont satisfaites :
| Type | Définition |
X
|
un type AllocatorAwareContainer |
T
|
le
value_type
de
X
|
A
|
le type d'allocateur utilisé par
X
|
| Valeur | Définition |
| a , b |
des lvalues non constantes de type
X
|
| c | une lvalue de type const X |
| t |
une lvalue ou une rvalue constante de type
X
|
| rv |
une rvalue non constante de type
X
|
| m |
une valeur de type
A
|
Types
| Nom | Type | Exigence |
|---|---|---|
| typename X :: allocator_type |
A
|
X::allocator_type::value_type
et
X::value_type
sont identiques.
|
Instructions
| Énoncé | Sémantique | Complexité | |
|---|---|---|---|
|
X u
;
X u = X ( ) ; |
Précondition |
A
est
DefaultConstructible
.
|
Constante |
| Postcondition | u. empty ( ) et u. get_allocator ( ) == A ( ) sont tous deux true . | ||
| X u ( m ) ; | Postcondition | u. empty ( ) et u. get_allocator ( ) == m sont tous deux true . | Constante |
| X u ( t, m ) ; | Précondition |
T
est
CopyInsertable
dans
X
.
|
Linéaire |
| Postcondition | u == t et u. get_allocator ( ) == m sont tous deux true . | ||
| X u ( rv ) ; | Postcondition |
|
Constante |
| X u ( rv, m ) ; | Précondition |
T
est
MoveInsertable
dans
X
.
|
|
| Postcondition |
|
||
Expressions
| Expression | Type | Sémantique | Complexité | |
|---|---|---|---|---|
| c. get_allocator ( ) |
A
|
Aucune exigence sémantique directe. | Constante | |
| a = t |
X&
|
Précondition |
T
est
CopyInsertable
dans
X
et
CopyAssignable
.
|
Linéaire |
| Postcondition | a == t est true . | |||
| a = rv |
X&
|
Précondition |
Si l'allocateur
ne sera pas
remplacé par l'affectation par déplacement (voir
ci-dessus
), alors
T
est
MoveInsertable
dans
X
et
MoveAssignable
.
|
Linéaire |
| Effet | Tous les éléments existants de a sont soit affectés par déplacement soit détruits. | |||
| Postcondition | Si a et rv ne font pas référence au même objet, a est égal à la valeur que rv avait avant l'affectation. | |||
| a. swap ( b ) | void | Effet | Échange le contenu de a et b . | Constante |
Notes
AllocatorAwareContainer
s appellent toujours
std::
allocator_traits
<
A
>
::
construct
(
m, p, args
)
pour construire un objet de type
T
à l'adresse
p
en utilisant
args
, avec
m
==
get_allocator
(
)
.
L'implémentation par défaut de
construct
dans
std::allocator
appelle
::
new
(
(
void
*
)
p
)
T
(
args
)
(jusqu'à C++20)
std::allocator
n'a pas de membre
construct
et
std::
construct_at
(
p, args
)
est appelée lors de la construction des éléments
(depuis C++20)
, mais les allocateurs spécialisés peuvent choisir une définition différente.
Bibliothèque standard
Tous les types de chaînes et conteneurs standards (à l'exception de std::array et std:: inplace_vector ) sont des AllocatorAwareContainer s :
|
stocke et manipule des séquences de caractères
(modèle de classe) |
|
|
file double face
(modèle de classe) |
|
|
(C++11)
|
liste simplement chaînée
(modèle de classe) |
|
liste doublement chaînée
(modèle de classe) |
|
|
tableau contigu redimensionnable
(modèle de classe) |
|
|
collection de paires clé-valeur, triées par clés, clés uniques
(modèle de classe) |
|
|
collection de paires clé-valeur, triées par clés
(modèle de classe) |
|
|
collection de clés uniques, triées par clés
(modèle de classe) |
|
|
collection de clés, triées par clés
(modèle de classe) |
|
|
(C++11)
|
collection de paires clé-valeur, hachées par clés, clés uniques
(modèle de classe) |
|
(C++11)
|
collection de paires clé-valeur, hachées par clés
(modèle de classe) |
|
(C++11)
|
collection de clés uniques, hachées par clés
(modèle de classe) |
|
(C++11)
|
collection de clés, hachées par clés
(modèle de classe) |
Rapports de défauts
Les rapports de défauts modifiant le comportement suivants ont été appliqués rétroactivement aux normes C++ précédemment publiées.
| DR | S'applique à | Comportement tel que publié | Comportement correct |
|---|---|---|---|
| LWG 2839 | C++11 | l'auto-affectation par déplacement des conteneurs standards n'était pas autorisée | autorisée mais le résultat n'est pas spécifié |