Cela peut être un peu spécifique à l'implémentation, mais certains d'entre eux semblent fondamentaux.Deleter personnalisé efficace en mémoire pour std :: unique_ptr?
Je suis certain que je dois manquer quelque chose dans la bibliothèque standard.
Le problème est le suivant:
Je veux mettre en œuvre un std::unique_ptr
dont Deleter est free()
[parce que la valeur est attribuée par malloc()
]
Il y a, bien sûr, beaucoup d'options sur comment faire cela, mais (au moins en g ++ 4.8.4 pour x86-64), ils semblent avoir des implications différentes d'utilisation de la mémoire.
Exemples: Méthode 1:
std::unique_ptr<char, std::function<void(void*)>> ptr_a(malloc(10), free);
Cependant, sizeof(ptr_a)
== 40 octets (8 pour void *, 32 pour std :: fonction <>)
Méthode 2:
std::unique_ptr<void, void (*)(void*)> ptr_b(malloc(10), free);
Un peu mieux, comme sizeof(ptr_b)
== 16 octets (8 pour void *, 8 pour fonct nu pointeur ion])
Méthode 3:
template <void (*T)(void*)>
class Caller {
public:
void operator()(void* arg) {
return T(arg);
}
};
std::unique_ptr<void, Caller<free>> ptr_c(malloc(10));`
A ce stade, sizeof(ptr_c)
== 8 octets (minimum possible) - mais j'ai dû introduire une classe qui est à peu près pur passe-partout (et, comme montré, facilement modélisé).
Cela ressemble à un modèle si simple - y a-t-il un élément dans la STL qui fait ce que fait Caller<>
ci-dessus? Bien sûr, g ++ par défaut apparaît bien free() lors de l'appel de delete sur un type trivial - mais cela semble loin d'être garanti par le standard (si rien d'autre, new/delete peut être redéfini à partir de l'allocation par défaut/les fonctions de deallocation, et default_delete appellera alors la suppression de remplacement).
De plus, il existe d'autres cas où la libération de certains objets alloués dans une bibliothèque C pure serait implémentée par un simple appel de fonction plutôt que par un suppresseur. Il semble fastidieux de devoir utiliser ces fonctions d'allocation/désallocation dans les classes pour que std :: unique_ptr les appelle correctement et efficacement, ce qui me laisse penser qu'il me manque quelque chose (la plupart des autres spécifications C++ modernes semble être extrêmement bien pensé).
Cet objet devient difficile de passer autour sans violer ODR entre les unités de compilation. – Yakk
Oui, vous avez raison. – Hakes