A question différente a inspiré la pensée suivante :
Fait std::vector<T>
ont pour déplacer tous les éléments lorsqu'elle augmente sa capacité ?
D'après ce que je comprends, le comportement standard est que l'allocateur sous-jacent demande un morceau entier de la nouvelle taille, puis déplace tous les anciens éléments, détruit les anciens éléments et désalloue l'ancienne mémoire.
Ce comportement semble être la seule solution correcte possible compte tenu de l'interface standard de l'allocateur. Mais je me demandais s'il ne serait pas judicieux de modifier l'allocateur pour qu'il propose une fonction reallocate(std::size_t)
qui renverrait un pair<pointer, bool>
et pourrait correspondre à la base de données realloc()
? L'avantage de cette solution serait que, dans le cas où le système d'exploitation peut réellement étendre la mémoire allouée, alors aucun déplacement ne devrait avoir lieu. Le booléen indiquerait si la mémoire a été déplacée.
( std::realloc()
n'est peut-être pas le meilleur choix, car nous n'avons pas besoin de copier les données si nous ne pouvons pas les étendre. Donc, en fait, nous préférons quelque chose comme extend_or_malloc_new()
. Edit : Peut-être qu'un is_pod
-La spécialisation basée sur les traits nous permettrait d'utiliser le réel realloc
y compris sa copie bit à bit. Mais pas en général).
Cela semble être une occasion manquée. Dans le pire des cas, vous pouvez toujours implémenter reallocate(size_t n)
comme return make_pair(allocate(n), true);
donc il n'y aurait pas de pénalité.
Y a-t-il un problème qui rende cette fonctionnalité inappropriée ou indésirable pour le C++ ?
Le seul conteneur qui pourrait en profiter est peut-être std::vector
mais là encore, c'est un conteneur assez utile.
Mise à jour : Un petit exemple pour clarifier. Current resize()
:
pointer p = alloc.allocate(new_size);
for (size_t i = 0; i != old_size; ++i)
{
alloc.construct(p + i, T(std::move(buf[i])))
alloc.destroy(buf[i]);
}
for (size_t i = old_size; i < new_size; ++i)
{
alloc.construct(p + i, T());
}
alloc.deallocate(buf);
buf = p;
Nouvelle mise en œuvre :
pair<pointer, bool> pp = alloc.reallocate(buf, new_size);
if (pp.second) { /* as before */ }
else { /* only construct new elements */ }