2010-03-28 4 views
4

J'ai un ensemble de pointeurs partagés:Retirer du std :: set <shared_ptr <T>> T *

std::set<boost::shared_ptr<T>> set; 

Et un pointeur:

T* p; 

Je voudrais efficacement supprimer l'élément de set égal à p, mais je ne peux pas le faire avec l'un des membres de l'ensemble, ou l'un des algorithmes standard, puisque T* est un type complètement différent de boost::shared_ptr<T>.

Quelques approches que je peux penser sont:

  • construire en quelque sorte une nouvelle shared_ptr du pointeur qui ne prendra pas la propriété de la pointe à la mémoire (solution idéale, mais je ne vois pas comment faire)
  • emballage/re-mise en œuvre shared_ptr afin que je puisse faire le
  • ci-dessus juste faire ma propre recherche binaire sur l'ensemble
+0

Pourquoi avez-vous ce pointeur T brut de toute façon? – dalle

+1

Pourquoi pas? Je me retrouve souvent avec des pointeurs intelligents dans la classe 'Factory' et seulement des pointeurs/références bruts à l'extérieur. L'extérieur n'a pas besoin de savoir comment je gère mes objets. –

Répondre

9

Construire un shared_ptr<T> à partir de T avec un null_deleter (voir boost:::shared_ptr FAQ). De cette façon, les types sont compatibles et vous n'avez pas à vous inquiéter de la suppression temporaire d'un objet par votre shared_ptr temporaire.

Ou, comme l'un des commentaires disent, si vous pouvez changer T pour hériter de enable_shared_from_this vous pourriez obtenir un ptr partagé correct de votre objet.

+0

Ah, merci! C'est la solution simple que je cherchais. – James

+0

+1 Darn, était sur le point de poster ceci. Je l'ai rejeté au début en raison de (fausse) idée que le suppresseur faisait partie du type 'shared_ptr'. –

+2

Il existe en fait une FAQ distincte pour obtenir un 'shared_ptr' de' this' dans la FAQ liée à cette réponse. Il semble y avoir un template de classe appelé 'enable_shared_from_this' qui, lorsqu'il est hérité, fournit un' weak_ptr' à 'this'. Voir http://www.boost.org/doc/libs/1_42_0/libs/smart_ptr/enable_shared_from_this.html. –

1

Si la raison d'utiliser l'ensemble est que vous devez trouver efficacement des pointeurs de type T, alors la réponse évidente est de ne pas en faire un ensemble de pointeurs partagés! Au lieu de cela, enveloppez l'ensemble dans une classe qui gère les durées de vie des pointeurs que l'ensemble contient.

+0

composition sur l'héritage! – Eric

+0

Cela semble être une grande quantité de travail comparé aux autres options (c'est pourquoi je ne l'ai pas listé!): Le temps _only_ que j'ai besoin de chercher par pointeur plutôt que shared_ptr est quand je supprime des objets (et les objets peuvent persister au-delà du retrait jusqu'à ce que le shared_ptr du dernier utilisateur soit détruit), je ne peux donc pas lier aveuglément la durée de vie des objets à leur présence dans le conteneur. – James

+0

@Eric - pas vraiment. 'std :: set shared_ptr >' est déjà une composition, pas un héritage. Neil suggère de composer les bonnes choses, au lieu de composer les mauvaises choses. –

1

Vous pouvez utiliser boost::ptr_set si vous souhaitez que l'ensemble soit propriétaire des objets, ou boost::reference_wrapper si vous voulez simplement que l'ensemble stocke des références. Si vous utilisez shared_ptr en un seul endroit dans votre code, vous devrez l'utiliser dans tous les endroits, ou risquer des accidents terribles (pointeurs qui pendent, objets déjà supprimés, etc.). L'exception est weak_ptr, un pointeur qui pointe vers un objet détenu par un shared_ptr mais ne partage pas la propriété.

+0

L'ensemble est un propriétaire des objets, mais d'autres utilisateurs peuvent persister après avoir été retirés de l'ensemble, donc 'boost :: ptr_set 'n'est pas approprié. Pour cette raison, je ne peux pas non plus utiliser 'reference_wrapper' ou' weak_ptr' car, dans les deux cas, les utilisateurs peuvent se retrouver avec des références pendantes. – James

+0

L'utilisation de pointeurs a également le risque de faire basculer les pointeurs. Pourquoi ne pouvez-vous pas supprimer les objets en utilisant un 'shared_ptr'? Pourquoi introduisez-vous un pointeur normal là? –

+0

effectivement je veux supprimer de l'intérieur d'une fonction membre des objets stockés, donc quelque part plus haut dans la pile il y a un shared_ptr faisant référence à l'objet, mais je ne veux pas avoir à le transmettre lorsque le pointeur this est facilement disponible. Fondamentalement, je veux faire: 'removeFromSet (this)' – James

Questions connexes