Re: C++0X : Rvalue references
Mickaël Wolff a écrit :
> Bonjour la liste,
>
> Je n'arrive pas à saisir le concept des « rvalue references », promis
> pour la prochaine normalisation du C++.
>
> À quoi cela correspond-t-il concrètement ? Quelle en est l'utilité
> pratique ?
>
> <http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2006/n2118.html>
>
> Merci pour vos éclaircissements.
Pour moi, les principaux apports sont :
1. la sémantique de déplacement (move semantic).
C'est à dire par exemple qu'au lieu de copier un objet puis de détruire
l'ancien, tu peux directement transférer l'objet à un autre endroit de
la mémoire.
C'est intéressant pour les swap par example où tu n'est plus obligé
d'appeler 1 constructeur par copie et deux opérateur par copie, tu fais
juste un move comme tu le ferais avec un memcpy pour des POD.
C'est aussi intéressant pour les ressources qui ne doivent pas être
dupliquées comme les mutex. C'est en fait une autre application de swap
(sans spécialisation requise). Ou encore pour faire la distinction entre
une copy où la ressource doit être dupliquée ou peut rester partagée
(comptage de référence).
2. Utilisation de temporaires en tant que paramètre non const.
Par exemple, ça veut dire que tu peux utiliser une valeur renvoyée par
une fonction en tant que paramètre non-const (Pour peu que la class soit
moveable).Une application pratique est une fonction get_log_stream() qui
te renvoie une stream que tu vas utiliser pour contruire un log; le log
est envoyé à la destruction de la stream.
logstream get_log_stream();
Aujourdhui, tu ne peux pas faire:
get_log_stream()<<"LOG: Error "<<errno<<std::endl;
Parce que les fonctions de stream sont de la forme:
template<typename T>
ostream& operator<<(ostream& os, const T& t)
{
// ...
return os;
}
Et donc tu ne peux pas mettre une temporaire en paramètre 'os' car il
n'est pas const.
Avec les reférences Rvalues:
template<typename T>
ostream& operator<<(ostream&& os, const T& t)
{
// ...
return std::forward<ostream>(os);
}
Tu peux ensuite faire:
get_log_stream()<<"LOG: Error "<<errno<<std::endl;
// destruction de la temporaire renvoyée par get_log_stream()
// et utiliser RAII pour faire ce que tu veux.
Michael
|