std :: vector quand certains membres de Foo sont des références

Je préfère souvent utiliser des références que des pointeurs chaque fois que possible, cela rend la syntaxe plus propre à mon avis. Dans ce cas, j’ai un cours:

class Foo { public: Foo(Bar & bar) : bar_(bar) {} private: Bar & bar_; }; 

operator=() est implicitement supprimé par le compilateur pour une telle classe, car une fois qu’une référence est définie, elle ne peut pas être modifiée (je peux techniquement définir la mienne qui ne change pas bar_, mais ce ne serait pas le comportement requirejs, donc Je préférerais que le compilateur se plaint si j’essaie d’assigner un toto).

Ce dont j’ai besoin, c’est d’un std::vector v; . Cela est impossible avant C ++ 11, car le paramètre de modèle doit être CopyAssignable. En effet, lorsque j’appelle v.push_back(Foo(bar)); , le compilateur se plaint. Mais je pense que cela pourrait être possible depuis la sémantique C ++ 11 et Move.

Ma question est la suivante: existe-t-il une solution de contournement utilisant C ++ 11 qui permettrait de créer un tel vecteur, ou suis-je bloqué dans ce cas et n’ai aucun moyen d’utiliser des pointeurs au lieu de références? S’il existe une solution de contournement, j’apprécierais beaucoup un extrait de code, car je ne connais pas bien la sémantique des déplacements.

Voila emplace_back est capable de faire le travail grâce à une transmission parfaite.

 #include  class Bar{}; class Foo { public: Foo(Bar & bar) : bar_(bar) {} private: Bar & bar_; }; using namespace std; int main() { vector v; Bar bar; v.emplace_back(bar); } 

Vous pouvez également stocker une référence par elle-même dans un conteneur avec std::reference_wrapper utilisé comme std::vector> v

Utilisez v.emplace_back(bar) au lieu de push_back . Il construira un Foo en place dans le vector mémoire alloué, ne nécessitant aucune copie. Il suffit de passer à emplace_back les arguments pour construire un Foo .

Le paramètre template d’un conteneur n’a pas besoin d’être CopyAssignable, cela dépend des opérations que vous effectuez sur votre conteneur, et si vous utilisez réellement une opération nécessitant CopyAssignable ou MoveAssignable, vous ne pouvez pas utiliser une référence à votre guise (même avec move sémantique). ). Mais si vous utilisez uniquement d’autres opérations (voir standard), tout ira bien. Certaines opérations ne nécessitaient que CopyInsertable, MoveInstable et / ou EmplaceConstructible.