IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Langage C++ Discussion :

Faut-il vraiment forcer l'utilisation de r-values ?


Sujet :

Langage C++

  1. #1
    Membre du Club
    Homme Profil pro
    C++
    Inscrit en
    Janvier 2013
    Messages
    45
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : C++

    Informations forums :
    Inscription : Janvier 2013
    Messages : 45
    Points : 44
    Points
    44
    Par défaut Faut-il vraiment forcer l'utilisation de r-values ?
    Bonjour cher Forumers,

    Je dispose d'une fonction (contexte) dont le rôle est d'instancier un objet, puis de le passer à une autre fonction.
    Clairement, le compilateur va optimiser le passage pour éviter de recopier l'objet. Mais faut-il insister en forçant l'utilisation de Rvalues ?

    Voici le code initial :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
     
            template <class DerivedType>
            void operator()(DerivedType& to_insert) const{
                auto buffer = deriveds.template insert<DerivedType&>(to_insert); //<-- Création
                start_visit(buffer); //<-- Passage
            }
     
            template <class Buffer>
            void start_visit(Buffer buffer) const{ //<-- Réception
                auto visitor = get_visitor(buffer);
                visitor.start_visit(buffer.top());
            }
    Voici le code avec Rvalues :
    - Un inconvenient des rvalues, c'est de rendre la lecture moins simple.
    - Et qu'il faut s'assurer que l'objet ne sera pas réutilisé...
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
     
            template <class DerivedType>
            void operator()(DerivedType& to_insert) const{
                auto&& buffer = deriveds.template insert<DerivedType&>(to_insert); //<-- Création
                start_visit(buffer); //<-- Passage
            }
     
            template <class Buffer>
            void start_visit(Buffer&& buffer) const{ //<-- Réception
                auto visitor = get_visitor(buffer);
                visitor.start_visit(buffer.top());
            }
    Qu'est-ce qui est préférable ? Dans quelles conditions ? Et pourquoi ?
    Merci d'avances pour vos réponses

  2. #2
    Invité
    Invité(e)
    Par défaut
    Le passage par rvalue ne sert que lorsque tu as un object que tu passes a une fonction ou à une variable membre et que tu es sûr de ne pas réutiliser l'objet passé à la fonction ou à la variable membre par après. (Attention, je ne parle pas de l'objet déclaré dans la fonction ou bien de la classe mais celui passé à la fonction ou bien à la classe)

    Par exemple si t'a un objet a que tu passes à une fonction f ou à un objet d'une classe c, si tu es sûr que tu ne devras plus passer l'objet a à une autre fonction f2 ou bien à un autre objet de la classe c. (Ou bien même d'une autre classe d)
    Alors tu peux forcer un passage par rvalue.

    Mais personnellement je ne le fais jamais car rien ne garantis que l'utilisateur de la librairie n'aura besoin de réutiliser les objets déclarés à l'extérieur de la librairie, au pire, je fais juste une copie de l'objet avant de le passé à la librairie (lors de l’initialisation) pour ne pas ralentir le code pendant la boucle d'exécution.

    Mais il y a quelques situations ou les rvalues sont vraiment plus utile :

    -Pour le perfect forwarding si tu veux passer des éléments par valeur ou bien par référence à une fonction par exemple pour les stocker ensuite dans un tuple. (Ou bien pour la passé à un wrapper)
    Le perfect forwarding est souvent utilisé pour éviter de devoir spécialiser une fonction template pour le passage par valeur ou bien pour le passage par référence. (La rvalue va automatiquement choisir la bonne spécialisation pour la fonction template et std::forwrard va automatiquement renvoyer une référence ou bien une valeur suivant le type passé en paramètre à la fonction template, si j'ai bien compris le principe du perfect forwarding.)

    -Pour le chargement de ressources très lourde (classes non copiables), alors là, j'appelle une fonction pour charger la ressource dans une sous classe qui est propriétaire de la ressource, et je déplace le contenu de la ressource chargée dans la variable membre de la sous classe.
    J'instancie les objets de cette sous classe dans un contenaire statique d'une classe de base pour m'assurer que les resssources soient bien détruites à la fin du programme. (Ceci m'évite de devoir utiliser un pointeur sur la ressource et me permet de conserver RAII, même si la ressource n'a pas été chargée, le fait d'utiliser une variable simple plutôt qu'un pointeur sur la ressource et de la passer à une variable membre d'une autre classe, me permet d'être sûr qu'elle est bien libérée si elle une exception est lancée pendant le chargement)

  3. #3
    Membre expert
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Juin 2011
    Messages
    739
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Hérault (Languedoc Roussillon)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels

    Informations forums :
    Inscription : Juin 2011
    Messages : 739
    Points : 3 627
    Points
    3 627
    Par défaut
    Citation Envoyé par Lolilolight Voir le message
    Le passage par rvalue ne sert que lorsque tu as un object que tu passes a une fonction ou à une variable membre et que tu es sûr de ne pas réutiliser l'objet passé à la fonction ou à la variable membre par après. (Attention, je ne parle pas de l'objet déclaré dans la fonction ou bien de la classe mais celui passé à la fonction ou bien à la classe)
    Mhouai, autant passer par valeur qui est beaucoup plus explicite. Côté utilisation, aucune différence, côté implémentation pareil.
    Le passage par rvalue pour un type connu je le voit plus comme: Si j'ai envie je deviens propriétaire (move) mais je peux ne pas avoir envie. La fonction à le choix de ne pas devenir propriétaire.

    Il y a plusieurs mois j'ai écrit un article à propos des rvalue, référence et valeur.

    Par contre, attention avec les auto&&, c'est plutôt une mauvaise idée et source d'erreur (un peu comme les const & sur temporaire).

    (Je te propose aussi de regarder ce qu'est la (N)RVO (entrée dans la faq) et l'elision (dans la faq ?))

Discussions similaires

  1. Forcer IE à utiliser la version du JRE de mon choix
    Par Nomade95000 dans le forum Applets
    Réponses: 7
    Dernier message: 18/08/2017, 19h10
  2. Logiciel pour forcer l'utilisation du proxy
    Par shawn12 dans le forum Administration
    Réponses: 2
    Dernier message: 02/08/2007, 11h49
  3. Réponses: 2
    Dernier message: 23/07/2007, 07h00
  4. [Framework]Comment Forcer l'utilisation du Framework 1.1
    Par michel71 dans le forum Framework .NET
    Réponses: 1
    Dernier message: 11/12/2006, 21h11
  5. Réponses: 20
    Dernier message: 19/09/2006, 20h52

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo