2017-03-07 3 views
0

Dire que j'ai une classe C le seul but est de remplir un conteneur con_m d'un certain type qui est membre de C. Donc, C possède des méthodes pour remplir con_m d'une manière spécifique. Après C a rempli con Je n'ai plus besoin de C, donc je veux vider con_n dans une autre variable. Mais C est en fait un foncteur dans le sens où con_m ne peut être rempli que de manière incrémentielle, donc ne peut pas être un objet local à la fonction de remplissage. Aussi l'implémentation doit être cachée à l'utilisateur, il n'a donc pas besoin d'appeler std::move sur la fonction retournant con_m.Est-ce que std :: move utilise un design acceptable?

template <class container_type> class C { 

public: 

    template <class T> void fill_some_more(const T &t) { 
    // do stuff with t filling con_m by another increment 
    } 

    container_type dump_container() { return std::move(con_m); } 

    container_type con_m; 
}; 

int main() { 
    C<std::vector<int>> c; 
    while (some_condition) { 
     c.fill_some_more(some_int); 
    } 
    auto con = c.dump_container(); 
} 

Est-ce une utilisation appropriée de std::move?

+3

Il semble que les méthodes de 'C' pourraient être mieux comme des fonctions autonomes qui prennent le conteneur en tant que paramètre. Vous n'aurez pas de problème à sortir le conteneur de la classe si ce n'est pas un membre en premier lieu. –

+1

Cela semble dépendre de savoir si votre constructeur de mouvement laisse l'objet source dans l'état souhaité –

+0

Je dirais non. En général, le constructeur de déplacement n'est pas obligé de laisser le conteneur vide. – immibis

Répondre

1

également la mise en œuvre doit être caché à l'utilisateur

Déplacement du contenu d'un objet est pas un détail de mise en œuvre; cela fait partie de ce que fait la fonction. En déplaçant le contenu de l'objet, vous faites en sorte que l'objet a perdu son contenu, et par conséquent le code qui est appelé plus tard doit respecter ce fait. La raison pour laquelle le comité de normalisation C++ a fait en sorte que vous deviez utiliser beaucoup explicitement std::move était que les gens lisant votre code seraient capables de savoir ce qui se passe. Si une personne voit c.dump_container(), ils vont probablement supposer que le dumping est arrivé par le biais de la copie. S'ils voient std::move(c).dump_container(), et s'ils voient qu'ils ne peuvent pas appeler sur une référence lvalue, il est très clair pour tout le monde impliqué ce que l'état de c sera par la suite.

Le mouvement devrait être explicite. Bien sûr, comme Igor l'a souligné dans les commentaires, tout cela pourrait être évité s'il s'agissait de fonctions libres agissant sur un conteneur fourni par l'utilisateur, plutôt que de devoir faire partie du conteneur.