Comment faire respecter la sémantique de déplacement lorsqu'un vecteur pousse?
J'ai un std::vector
des objets d'une certaine classe A
. La classe est non-trivial et a copier les constructeurs et constructeurs de déplacement définie.
std::vector<A> myvec;
Si je remplir le vecteur avec A
objets (en utilisant par exemple myvec.push_back(a)
), le vecteur va croître en taille, en utilisant le constructeur de copie A( const A&)
pour instancier de nouvelles copies des éléments d'un vecteur.
Je peux en quelque sorte faire valoir ce que de le déplacer, le constructeur de la classe A
est commencer utilisée à la place?
Vous pouvez, en utilisant un mouvement conscient de vecteur de mise en œuvre.
Pouvez-vous s'il vous plaît être un peu plus spécifique comment atteindre cet objectif?
Il vous suffit d'utiliser un mouvement conscient de vecteur de mise en œuvre. Il semble que votre bibliothèque standard de mise en œuvre (qui est-il d'ailleur?) n'est pas le déplacer. Vous pouvez essayer avec move-connaissance des conteneurs à partir de Boost.
Eh bien, je-je utiliser gcc 4.5.1, qui est au courant.
Dans mon code, il a travaillé à faire de l'constructeur de copie privée, même si le constructeur de déplacement n'ont pas l'explicite "noexcept".
Pouvez-vous s'il vous plaît être un peu plus spécifique comment atteindre cet objectif?
Il vous suffit d'utiliser un mouvement conscient de vecteur de mise en œuvre. Il semble que votre bibliothèque standard de mise en œuvre (qui est-il d'ailleur?) n'est pas le déplacer. Vous pouvez essayer avec move-connaissance des conteneurs à partir de Boost.
Eh bien, je-je utiliser gcc 4.5.1, qui est au courant.
Dans mon code, il a travaillé à faire de l'constructeur de copie privée, même si le constructeur de déplacement n'ont pas l'explicite "noexcept".
OriginalL'auteur Bertwim van Beest | 2011-11-03
Vous devez vous connecter pour publier un commentaire.
Vous devez informer C++ (plus précisément
std::vector
) que votre constructeur et le destructeur ne les jetez pas, à l'aide denoexcept
. Ensuite, le constructeur de déplacement sera appelée lorsque le vecteur grandit.C'est la façon de déclarer et de mettre en œuvre un mouvement constuctor qui est respecté par
std::vector
:Si le constructeur n'est pas
noexcept
,std::vector
ne pouvez pas l'utiliser, car il ne peut pas assurer l'exception des garanties exigées par la norme.Pour en savoir plus sur ce qui est dit dans la norme, lire
C++ sémantique de Déplacement et les Exceptions
De crédit à la Bo qui a laissé entendre qu'il peut avoir à faire avec des exceptions. Également envisager de Kerrek SB conseils et de l'utilisation
emplace_back
lorsque cela est possible. Il peut être plus rapide (mais n'est souvent pas), il peut être plus claire et plus compact, mais il y a aussi des pièges à éviter (surtout avec les non-explicite constructeurs).Modifier, souvent la valeur par défaut est ce que vous voulez: déplacer tout ce qui peut être déplacé, copiez le reste. Demander explicitement que, écrivez
En faisant cela, vous obtiendrez noexcept quand c'est possible: La valeur par défaut est constructeur de Déplacement définie comme noexcept?
Noter que les premières versions de Visual Studio 2015 et plus n'a pas soutenu que, même si elle prend en charge la sémantique de déplacement.
value_type
's move ctor estnoexcept
? Peut-être la langue restreint l'appel de la fonction ensemble candidat lors de l'appel de la portée est également unnoexcept
fonction?Je suppose que c'est juste de faire quelque chose comme en.cppreference.com/w/cpp/types/is_move_constructible. Il peut être un seul constructeur de déplacement de sorte qu'il devrait être clairement définie par la déclaration.
Depuis, j'ai appris qu'il n'y est pas (standard/utile) façon de vraiment savoir si il existe un
noexcept
constructeur de déplacement.is_nothrow_move_constructible
sera vrai si il y a unnothrow
constructeur de copie. Je ne suis pas au courant de cas réel de chernothrow
copie des constructeurs de sorte qu'il n'est pas évident que cela compte vraiment.OriginalL'auteur Johan Lundberg
Il est intéressant de noter, gcc 4.7.2 du vecteur utilise uniquement constructeur de déplacement si le déplacer constructeur et le destructeur sont
noexcept
. Un exemple simple:Ce extrants attendus:
Cependant, quand j'enlève
noexcept
de~foo()
, le résultat est différent:Je suppose que cela répond également cette question.
Bon point, mais le destructeur est noexcept par défaut.
Eh bien, il devrait être, mais comme il s'avère, dans gcc 4.7.2 il n'était pas. Donc, ce problème a été, en fait, spécifiques à la gcc. Il doit être fixé dans gcc 4.8.0, cependant. Voir liées stackoverflow question.
OriginalL'auteur Nikola Benes
Il semble que le seul moyen (pour le C++17 et au début de l') afin de faire respecter
std::vector
utiliser la sémantique de déplacement sur la réaffectation est la suppression de constructeur de copie 🙂 . De cette façon, il va utiliser vos constructeurs de déplacement ou de mourir en essayant, au moment de la compilation :).Il y a beaucoup de règles où
std::vector
ne DEVEZ PAS utiliser constructeur de déplacement sur la réaffectation, mais rien sur l'endroit où il DEVEZ UTILISER.Live
ou
Code en direct
Votre
T
classe doit avoirnoexcept
déplacer constructeur/opérateur d'affectation etnoexcept
destructeur. Sinon vous obtiendrez d'erreur de compilation.Il PEUT être utilisé. La norme n'exige pas de cela maintenant. Voici la discussion groups.google.com/a/isocpp.org/forum/...
OriginalL'auteur tower120