Scelta citazione da cppreference:
Questo runtime polimorfismo permette agli oggetti che utilizzano polymorphic_allocator a comportarsi come se fossero utilizzati diversi tipi allocatore in fase di esecuzione, nonostante l'identica statica tipo allocatore
Il problema con " regolari "allocatori è che cambiano il tipo del contenitore. Se si desidera un vector
con un allocatore specifico, è possibile utilizzare il parametro di Allocator
modello:
auto my_vector = std::vector<int,my_allocator>();
Il problema ora è che questo vettore non è dello stesso tipo di un vettore con un allocatore diverso. Non è possibile passare ad una funzione che richiede un vettore default-allocatore, per esempio, o assegnare due vettori con un diverso tipo allocatore alla stessa/puntatore variabile, ad esempio:
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 allocatore polimorfico è un tipo di allocatore singolo con un membro che può definire il comportamento di allocatore tramite dispatch dinamico anziché tramite il meccanismo di modello. Ciò consente di disporre di contenitori che utilizzano allocazioni specifiche e personalizzate, ma che sono ancora di un tipo comune.
La personalizzazione del comportamento allocatore è fatto dando l'allocatore un 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
La principale questione in sospeso, come la vedo io, è che un contenitore std::pmr::
non è ancora compatibile con l'equivalente std::
container usando l'allocatore predefinito.Hai bisogno di fare alcune decisioni al momento di progettare un'interfaccia che funziona con un contenitore:
- è probabile che il contenitore in passato può richiedere l'assegnazione personalizzato?
- in tal caso, dovrei aggiungere un parametro modello (per consentire allocatori arbitrari) o dovrei richiedere l'uso di un allocatore polimorfico?
Una soluzione di modello permette qualsiasi allocatore, compreso un allocatore polimorfico, ma presenta altri inconvenienti (dimensioni codice generato, tempo di compilazione, codice deve essere esposta nel file di intestazione, potenziale di ulteriore "tipo contaminazione" che mantiene spingendo il problema verso l'esterno). D'altra parte, una soluzione di allocazione polimorfica stabilisce che un allocatore polimorfico deve essere utilizzato. Ciò preclude l'utilizzo dei contenitori std::
che utilizzano l'allocatore predefinito e potrebbero avere implicazioni per l'interfaccia con il codice legacy.
Rispetto a un allocatore regolare, un allocatore polimorfico presenta alcuni costi minori, come il sovraccarico di memoria del puntatore memory_resource (che è probabilmente trascurabile) e il costo della distribuzione di funzioni virtuali per le allocazioni. Il problema principale, in realtà, è probabilmente la mancanza di compatibilità con il codice legacy che non utilizza allocatori polimorfici.
Provano a superare alcuni problemi 'allocatore' intrinsecamente. Quindi vedrai il valore in esso se usi frequentemente gli allocatori. –
edmz
Relevant [paper] (http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2013/n3525.pdf). – edmz
@black Davvero interessante, grazie. Ne varrebbe la pena aggiungere una risposta con questa roba? – skypjack