web-dev-qa-db-fra.com

Réutiliser un conteneur déplacé?

Quelle est la bonne façon de réutiliser un conteneur déplacé?

std::vector<int> container;
container.Push_back(1);
auto container2 = std::move(container);

// ver1: Do nothing
//container2.clear(); // ver2: "Reset"
container = std::vector<int>() // ver3: Reinitialize

container.Push_back(2);
assert(container.size() == 1 && container.front() == 2);

De ce que j'ai lu dans le brouillon standard C++ 0x; ver3 semble être la bonne voie, puisqu'un objet après le déménagement est dans un

"Sauf indication contraire, de tels objets déplacés sont placés dans un état valide mais non spécifié."

Je n'ai jamais trouvé d'instance là où il est "sinon spécifié".

Bien que je trouve VER3 un bit rond-point et aurait beaucoup préféré VER1, bien que Vec3 puisse permettre une optimisation supplémentaire, mais d'autre part peut facilement conduire à des erreurs.

Mon hypothèse est-elle correcte?

80
ronag

L'objet étant dans un valide, mais non défini signifie fondamentalement que, si l'état exact de l'objet n'est pas garanti, il est valide et comme de telles fonctions membres (ou des fonctions non membres) sont garantis pour travailler aussi longtemps qu'ils ne comptent pas sur l'objet ayant un certain État.

La fonction de membre clear() n'a aucune condition préalable à l'état de l'objet (autre que celle qu'elle est valide, bien sûr) et peut donc être appelée sur des objets déplacés. D'autre part, par exemple, front() dépend du conteneur non vide et ne peut donc pas être appelé, car il n'est pas garanti d'être non vide.

Par conséquent, Ver2 et Ver3 devraient tous les deux aller.

10
Grizzly