c++ unique_ptr argument en passant

Supposons que j'ai le code suivant:

class B { /* */ };

class A {
    vector<B*> vb;
public:
    void add(B* b) { vb.push_back(b); }
};


int main() {

    A a;
    B* b(new B());
    a.add(b);
}

Supposons que, dans ce cas, tous les pointeurs B* peut être gérée par le biais d' unique_ptr<B>.

Étonnamment, je n'ai pas réussi à trouver comment faire pour convertir ce code en utilisant unique_ptr. Après quelques essais, je suis venu avec le code suivant, qui compile:

class A {
    vector<unique_ptr<B>> vb;
public:
    void add(unique_ptr<B> b) { vb.push_back(move(b)); }
};


int main() {

    A a;
    unique_ptr<B> b(new B());
    a.add(move(b));
}

Donc ma question est simple: est-ce la façon de le faire et, en particulier, est move(b) la seule façon de le faire? (Je pensais à des références rvalue mais je ne comprends pas tout.)

Et si vous avez un lien avec des explications complètes de la sémantique de déplacement, unique_ptr, etc. que je n'étais pas en mesure de trouver, n'hésitez pas à le partager.

MODIFIER Selon http://thbecker.net/articles/rvalue_references/section_01.html, mon code semble être OK.

En fait, std::move est juste sucre syntaxique. Avec un objet x de la classe X, move(x) est la même chose que:

static_cast <X&&>(x)

Ces 2 déplacez fonctions sont nécessaires, car un casting pour une rvalue reference:

  1. empêche la fonction "ajouter" de passage par valeur
  2. fait push_back utiliser la valeur par défaut de déplacer le constructeur de B

Apparemment, je n'ai pas besoin de la deuxième std::move dans mon main() si je change ma "ajouter" fonction passage par référence (ordinaire lvalue réf.).

Je voudrais une confirmation de tout cela, mais...

Je pense que cela peut être utile pour vous: stackoverflow.com/questions/2876641/...
Merci, la question a donné des liens intéressants (voir EDIT)
Vous pouvez éviter l' std::move principale, si vous avez changé d'ajouter cette façon, mais ce serait mauvais, parce que l'appelant de add n'ai aucune idée si ils toujours la propriété de l'objet ou pas, sans chercher à la source de add.
Argh. Je savais que j'allais faire quelque chose de stupide. Merci. BTW, je pensais passer ma paramètre par référence rvalue, c'est à dire "ajouter(B&& b)", dans le but de supprimer le "déplacer" dans sa mise en œuvre, qui semble redondant dans ce cas. Mais, ce faisant (en passant par rvalue réf plutôt que par valeur), j'obtiens les mêmes résultats, et en particulier, je ne peux pas supprimer ce "mouvement". Quelle en est la raison ?
Parce que toutes les variables sont lvalues, y compris ceux qui sont des références à des rvalues.

OriginalL'auteur Bérenger | 2012-09-22