Citation de choix de cppreference :
Ce polymorphisme d'exécution permet aux objets utilisant polymorphic_allocator de se comporter comme s'ils utilisaient des types d'allocateur différents au moment de l'exécution, malgré un type d'allocateur statique identique.
Le problème des allocateurs "ordinaires" est qu'ils modifient le type de conteneur. Si vous voulez un vector
avec un allocateur spécifique, vous pouvez utiliser la fonction Allocator
paramètre du modèle :
auto my_vector = std::vector<int,my_allocator>();
Le problème maintenant est que ce vecteur n'est pas du même type qu'un vecteur avec un allocateur différent. Vous ne pouvez pas le passer à une fonction qui requiert un vecteur avec un allocateur par défaut, par exemple, ou assigner deux vecteurs avec un type d'allocateur différent à la même variable/pointeur, par exemple :
auto my_vector = std::vector<int,my_allocator>();
auto my_vector2 = std::vector<int,other_allocator>();
auto vec = my_vector; // ok
vec = my_vector2; // error
Un allocateur polymorphe est un type d'allocateur unique avec un membre qui peut définir le comportement de l'allocateur par le biais de la répartition dynamique plutôt que par le mécanisme de modèle. Cela vous permet d'avoir des conteneurs qui utilisent une allocation spécifique et personnalisée, mais qui sont toujours d'un type commun.
La personnalisation du comportement de l'allocateur se fait en donnant à l'allocateur un nom d'utilisateur et un mot de passe. std::memory_resource *
:
// define allocation behaviour via a custom "memory_resource"
class my_memory_resource : public std::pmr::memory_resource { ... };
my_memory_resource mem_res;
auto my_vector = std::pmr::vector<int>(0, &mem_res);
// define a second memory resource
class other_memory_resource : public std::pmr::memory_resource { ... };
other_memory_resource mem_res_other;
auto my_other_vector = std::pmr::vector<int>(0, &mes_res_other);
auto vec = my_vector; // type is std::pmr::vector<int>
vec = my_other_vector; // this is ok -
// my_vector and my_other_vector have same type
Le principal problème restant, tel que je le vois, est qu'une std::pmr::
n'est toujours pas compatible avec le conteneur équivalent std::
en utilisant l'allocateur par défaut. Vous devez prendre certaines décisions au moment où vous concevez une interface qui fonctionne avec un conteneur :
- est-il probable que le conteneur transmis nécessite une allocation personnalisée ?
- Dans ce cas, dois-je ajouter un paramètre de modèle (pour permettre des allocateurs arbitraires) ou dois-je imposer l'utilisation d'un allocateur polymorphe ?
Une solution modèle permet de cualquier y compris un allocateur polymorphe, mais présente d'autres inconvénients (taille du code généré, temps de compilation, code devant être exposé dans le fichier d'en-tête, potentiel de "contamination de type" supplémentaire qui repousse toujours le problème vers l'extérieur). D'autre part, la solution de l'allocateur polymorphe impose qu'un allocateur polymorphe debe être utilisé. Cela exclut l'utilisation de std::
qui utilisent l'allocateur par défaut, ce qui peut avoir des conséquences sur l'interfaçage avec le code existant.
Par rapport à un allocateur ordinaire, un allocateur polymorphe a quelques coûts mineurs, tels que l'overhead de stockage du pointeur memory_resource (qui est très probablement négligeable) et le coût de la répartition des fonctions virtuelles pour les allocations. Le principal problème, en fait, est probablement le manque de compatibilité avec le code existant qui n'utilise pas d'allocateurs polymorphes.
1 votes
Ils essaient de surmonter certains problèmes
allocator<T>
a par nature. Vous y verrez donc de la valeur si vous utilisez fréquemment des allocateurs.3 votes
Pertinent papier .
0 votes
Ce site papier explique en détail les idées derrière le polymorphic_allocator.