mouvement dans votre fonction:
// foo() decalaration
void foo(std::vector<int> v);
// usage example
std::vector<int> v {0, 1, 2, 3};
foo(std::move(v));
// v is moved into foo() and invalid now
Vous pouvez également retourner ce vecteur de la fonction de la même manière:
// foo() decalaration
std::vector<int> foo(std::vector<int> v) {
return v.push_back(4), std::move(v);
}
// usage example
std::vector<int> v {0, 1, 2, 3};
v = foo(std::move(v));
// now v is {0, 1, 2, 3, 4} and no one were deep copied
Mais notez si vous ne déplacer il (appel foo(v)
au lieu de foo(std::move(v))
) alors il sera copié profonde. Sous le capot, le paramètre v
de foo()
est simplement construit par move-constructor.
passe comme référence:
// foo() declaration
void foo(std::vector<int>& v);
Mais maintenant, nous avons un problème: qui référence et cv-qualifiés?Eh bien, en général, nous avons 2 types de références et 4 types de cv-qualifiés, au total 8 déclarations:
void foo(std::vector<int>&);
void foo(std::vector<int> const&);
void foo(std::vector<int> volatile&);
void foo(std::vector<int> const volatile&);
void foo(std::vector<int>&&);
void foo(std::vector<int> const&&);
void foo(std::vector<int> volatile&&);
void foo(std::vector<int> const volatile&&);
Bien sûr, une partie d'entre eux sont inutiles et devraient être supprimés. Mais néanmoins trop de déclarations aussi connu comme problème de transfert parfait (en fait, il n'y avait pas de références rvalue quand il y avait un problème donc le problème était 2 fois plus petit).
Par exemple, si vous souhaitez modifier v
vous avez besoin de 2 fonctions au moins:
void foo(std::vector<int>&);
void foo(std::vector<int>&&);
Dans ce cas, vous pourrez appeler foo()
sur des objets lvalue:
std::vector<int> v;
foo(v);
ainsi comme sur temporaire:
foo(std::vector<int>{1, 2, 3, 4, 5});
Mais comment code juste une implémentation pour différents types de référence et/ou cv-qualificatifs? Permettez-moi de vous présenter références universelles:
template<typename Vector>
void foo(Vector&& v);
Vector&&
est-toujours un type de référence et peut être déduit dans
std::vector<int>&
si vous passez lvalue de type std::vector<int>
dans foo()
:
std::vector<int> v;
foo(v); // v is lvalue
std::vector<int> const&
si vous passez const lvalue de type std::vector<int>
:
std::vector<int> const v;
foo(v); // v is const lvalue
std::vector<int>&&
si vous passez rvalue:
foo(std::vector<int>{0, 1, 2}); // v is rvalue
etc ...
Mais dans ce cas, vous avez pour vérifier l'acceptation du type Vector
. Mais c'est une autre histoire.
Si vous n'avez pas besoin de le modifier, alors 'const std :: vector &'. –
Cela fonctionnera-t-il pour les valeurs? – dwoodwardgb
en outre, probablement vous avez oublié _cv-qualificateurs _... – Nevermore