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

C++ Discussion :

Exercice C++ : des push_back transactionnels [D�bat]


Sujet :

C++

  1. #41
    Membre chevronn�

    Homme Profil pro
    D�veloppeur informatique
    Inscrit en
    Juin 2007
    Messages
    373
    D�tails du profil
    Informations personnelles :
    Sexe : Homme
    �ge : 36
    Localisation : Royaume-Uni

    Informations professionnelles :
    Activit� : D�veloppeur informatique
    Secteur : Sant�

    Informations forums :
    Inscription : Juin 2007
    Messages : 373
    Par d�faut
    Citation Envoy� par germinolegrand Voir le message
    pour compter la taille d'un variadic, il y a l'operateur sizeof...()
    �a aide Merci pour l'info !

    Citation Envoy� par germinolegrand Voir le message
    l� tes conteneurs sont aussi d�plac�s (vous confirmez ?).
    Il semblerait que non, cf. le code suivant.
    Code : S�lectionner tout - Visualiser dans une fen�tre � part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    struct C {
        std::vector<int> v;
        C() { std::cout << "C()" << std::endl; }
        C(const C& c) : v(c.v) { std::cout << "C(const C&)" << std::endl; }
        C(C&& c) : v(std::move(c.v)) { std::cout << "C(C&&)" << std::endl; }
     
        void insert(std::vector<int>::iterator iter, int&& i) {
            v.insert(iter, std::move(i));
        }
        void insert(std::vector<int>::iterator iter, const int& i) {
            v.insert(iter, i);
        }
        void erase(std::vector<int>::iterator iter) {
            v.erase(iter);
        }
        std::vector<int>::iterator end() { return v.end(); }
    };
     
    int main() {
        C va;
        safePushBack(va, 1, va, 2);
        std::cout << va.v.size() << std::endl;
    }
    ... qui affiche :
    C()
    2
    Par contre j'ai fait une erreur. Il ne faut pas utiliser std::move mais std::forward, sinon on d�place toujours les objets (m�me quand l'utilisateur donne une l-value) :
    Code : S�lectionner tout - Visualiser dans une fen�tre � part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    template <class C, class T>
    static inline void safePushBack(C& cont, T&& i)
    {
        cont.insert(std::end(cont), std::forward<T>(i));
    }
     
    template <class C, class T, class ... Args>
    static inline void safePushBack(C& cont, T&& i, Args&&... args)
    {
        cont.insert(std::end(cont), std::forward<T>(i));
        try
        {
            safePushBack(std::forward<Args>(args)...);
        }
        catch(...)
        {
            cont.erase(std::end(cont));
            throw;
        }
    }

  2. #42
    Membre Expert

    Avatar de germinolegrand
    Homme Profil pro
    D�veloppeur de jeux vid�o
    Inscrit en
    Octobre 2010
    Messages
    738
    D�tails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Puy de D�me (Auvergne)

    Informations professionnelles :
    Activit� : D�veloppeur de jeux vid�o
    Secteur : Tourisme - Loisirs

    Informations forums :
    Inscription : Octobre 2010
    Messages : 738
    Par d�faut
    Ah oui ^^ c'est surtout pour le std::move que je me disais que �a bougeait tout ^^
    Mais std::forward sur une r-value, �a fais bien un move non ?

  3. #43
    Membre chevronn�

    Homme Profil pro
    D�veloppeur informatique
    Inscrit en
    Juin 2007
    Messages
    373
    D�tails du profil
    Informations personnelles :
    Sexe : Homme
    �ge : 36
    Localisation : Royaume-Uni

    Informations professionnelles :
    Activit� : D�veloppeur informatique
    Secteur : Sant�

    Informations forums :
    Inscription : Juin 2007
    Messages : 373
    Par d�faut
    std::move transforme son argument en r-value, quel qu'il soit. Donc l� oui : si on utilise std::move partout, les conteneurs et les objets stock�s sont d�plac�s, ce qui peut cr�er son lot de surprises.

    Par contre std::forward garde les l-values comme des l-values, et les r-values comme des r-values. Donc oui, std::forward sur une r-value c'est comme std::move, mais sur une l-value �a ne fait rien. Maintenant, la signature de la fonction est trompeuse... On pourrait croire que, comme les arguments sont d�clar�s comme �tant de type Args&& ..., ce sont tous des r-values. Mais ce n'est pas le cas. Un exemple simplifi� :
    Code : S�lectionner tout - Visualiser dans une fen�tre � part
    1
    2
    template<typename T>
    void foo(T&& t);
    Si on appelle foo avec comme argument une l-value U u;, alors dans foo(u), u est d'abord interpr�t� comme �tant de type T == U&, et la r�gle (sp�cifique au cas template) est alors (U&)&& == U& : l'argument n'est pas du tout une r-value... Et c'est gr�ce � �a que std::forward fonctionne.

    En revanche, si on appelle foo avec comme argument une r-value, on a deux possibilit�s :
    • foo(U()) : on a T == U, et la r�gle est triviale : (U)&& == U&&,
    • foo(std::move(u)) : on a T == U&&, et la r�gle est : (U&&)&& == U&&.

    (source : open-std.org)

    En r�sum� dans ce genre de situation :
    • si on utilise std::move, tout est d�plac� (�a peut �tre grave et contre-intuitif si pas document�),
    • si on n'utilise rien, les r-values qui auraient pu �tre d�plac�es seront copi�es (c'est dommage),
    • si on utilise std::forward, ce qui peut �tre d�plac� sans cons�quence (les r-values) est d�plac�, et ce qui n'a pas raison de l'�tre (les l-values) ne l'est pas.

Discussions similaires

  1. Exercice - Gestion des employ�s d'une banque
    Par Adnane-Xx dans le forum C
    R�ponses: 2
    Dernier message: 03/06/2014, 17h00
  2. [sh] Exercice concat�nation des lignes impaires d'un fichier
    Par ettar dans le forum Shell et commandes GNU
    R�ponses: 6
    Dernier message: 29/05/2014, 13h02
  3. cr�er des feuilles d'exercices avec des corrig�s
    Par Dexter80 dans le forum Mise en forme
    R�ponses: 5
    Dernier message: 22/08/2012, 18h10
  4. exercice th�orie des langages
    Par abdellah 1 dans le forum Algorithmes et structures de donn�es
    R�ponses: 1
    Dernier message: 18/04/2009, 00h14
  5. R�ponses: 4
    Dernier message: 27/02/2005, 21h43

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