160 votes

Quand utiliser std::forward pour transmettre des arguments ?

C++0x montre un exemple d'utilisation de std::forward:

template<class T>
void foo(T&& arg) 
{
  bar(std::forward<T>(arg));
}

Quand est-il avantageux d'utiliser std::forward, toujours?

Aussi, il nécessite d'utiliser && dans les paramètres de déclaration, est-il valable dans tous les cas? J'ai pensé que vous deviez passer temporaires à une fonction si la fonction a été déclarée avec && elle, peut foo être appelée avec un paramètre?

Enfin, si j'ai un appel de fonction comme ceci:

template<int val, typename... Params>
void doSomething(Params... args) {
  doSomethingElse<val, Params...>(args...);
}

Dois-je l'utiliser à la place:

template<int val, typename... Params>
void doSomething(Params&&... args) {
  doSomethingElse<val, Params...>(std::forward<Params>(args)...);
}

Aussi, si l'option utiliser les paramètres par deux fois dans la fonction, c'est à dire la transmission à deux fonctions en même temps, est-il sage d'utiliser std::forward? Ne std::forward convertir la même chose de temporaire de deux fois, le déplacement de la mémoire et de la rendre invalide pour une seconde utilisation? Serait le code suivant être ok:

template<int val, typename... Params>
void doSomething(Params&&... args) {
  doSomethingElse<val, Params...>(std::forward<Params>(args)...);
  doSomethingWeird<val, Params...>(std::forward<Params>(args)...);
}

Je suis un peu confus par std::forward, et je me ferais un plaisir de les utiliser certaines de compensation.

131voto

Kerrek SB Points 194696

L'utiliser comme votre premier exemple:

template <typename T> void f(T && x)
{
  g(std::forward<T>(x));
}

template <typename ...Args> void f(Args && ...args)
{
  g(std::forward<Args>(args)...);
}

C'est à cause de la référence de l'effondrement des règles: Si T = U&, alors T&& = U&, mais si l' T = U&&, alors T&& = U&&, de sorte que vous vous retrouvez toujours avec le bon type à l'intérieur du corps de la fonction. Enfin, vous avez besoin d' forward à son tour la lvalue tourné x "(car il a un nom maintenant!) de retour en référence rvalue si c'était un premier temps.

Vous ne pouvez pas transférer de quelque chose plus d'une fois, cependant, parce que ça n'a aucun sens. Transfert signifie que vous êtes potentiellement en mouvement l'argument tout le chemin jusqu'à la finale de l'appelant, et une fois qu'il est déplacé, il s'en est allé, de sorte que vous ne pouvez pas l'utiliser à nouveau.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X