Ce que tu décris là, une classe gérant un conteneur et ayant une sémantique de conteneur, c'est (la généricité en moins dans ton exemple), l'idée d'un adaptateur de conteneurs. Là on parle hors de tout contexte, donc ta conclusion est prématuré AMA, un adaptateur de conteneur peut avoir une responsabilité parfaitement définie.
Si la classe a une sémantique de conteneur, Demeter ne s'applique pas sur lui. Pour le reste, en effet on ne sait pas (hors documentation (*)), que le pointeur retourné par le conteneur n'a pas à être pris en responsabilité. Ou plus exactement (et c'est ce qui appuie les propos de Loic si j'ai bien compris), l'existance d'une évolution dans le C++ fait qu'on ne sait pas avec certitude si le code est du "C++ moderne" où dans ce cas T* est membre du couple std::unique_ptr/T* (**) et donc qu'il n'a aucune responsabilité, où si c'est du C++ "plus ancien" où il n'y a pas de vraie sémantique associé à T*.
Je trouve que la lien est incomplet. Dans le contexte actuelle, le besoin d'une conversion implicite d'un std::unique_ptr vers un no_own_ptr (représenté par T* actuellement), n'est pas un besoin sans intérêt. Bien entendue l'argumentaire reste totalement valide pour une fonction get pensée dans l'esprit retro-compatibilité, comme pour std::shared_ptr, ce qui appuie encore l'idée de Loic d'un besoin d'un capsule no_own_ptr (peu importe le nom) pour séparer les deux utilités actuellement tenues par un seul élément). Dans le cas d'une telle capsule, il n'y aurait pas besoin d'écrire un opérateur de cast, le constructeur de no_own_ptr devrait suffire (comme pour std::shared_ptr/std::weak_ptr).
(*) Et c'est pas le seul élément du C++ où le besoin de documentation est nécessaire pour savoir quoi faire.
(**) Si on occulte totalement le besoin de se marier avec du code "ancien" le besoin d'un T* pour représenter autre chose qu'un pointeur sans responsabilité est quasi-nul.
Partager