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

SL & STL C++ Discussion :

std::vector semble ne pas utiliser std::move, pourquoi ?


Sujet :

SL & STL 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 std::vector semble ne pas utiliser std::move, pourquoi ?
    Bonjour a tous,
    J'ai fait quelques tests en mettant des cout dans les constructeurs de copy et constructeurs move d'une classe Obj
    J'ai ensuite fait plusieurs push back sur un vector<Obj>...
    Et il semble que lors de la réallocation c'est a dire quand le vector "s'agrandit", le vector recopie les données plutôt que de les déplacer... Est-ce normal ?

    Voici l'output de mon code :
    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
     
    first push back 
    constructing num1{} rvalue
    constructing num1 from '' using move constructor
     
    second push back 
    constructing num2{} rvalue
    constructing num2 from '' using move constructor
    constructing num1 from 'num1' using copy constructor
     
    third push back 
    constructing num3{} rvalue
    constructing num3 from '' using move constructor
    constructing num2 from 'num2' using copy constructor
    constructing num1 from 'num1' using copy constructor
    Voici le code du main :
    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
     
    int main(int argc, const char * argv[])
    {
        vector<Obj> vect;
     
        cout << endl << "first push back " << endl;
        vect.push_back(Obj("num1"));
     
        cout << endl << "second push back " << endl;
        vect.push_back(Obj("num2"));
     
     
        cout << endl << "third push back " << endl;
        vect.push_back(Obj("num3"));
     
        return 0;
    }
    Enfin voici la classe Obj :
    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
     
    class Obj{
     
        string name;
     
    public:
        Obj(const string & nom) : name{nom} {
            cout << "constructing " << name << "{" << nom << "} lvalue" << endl;
        }
        Obj(string&& nom) : name{move(nom)} {
            cout << "constructing " << name << "{" << nom << "} rvalue" << endl;
        }
     
        Obj(const Obj& source) : name{source.name} {
            cout << "constructing " << name << " from '" << source.name << "' using copy constructor" << endl;
        }
        Obj(Obj&& source) : name{move(source.name)}{
            cout << "constructing " << name << " from '" << source.name << "' using move constructor" << endl;
         }
    };

  2. #2
    Membre éclairé

    Homme Profil pro
    Non disponible
    Inscrit en
    Décembre 2012
    Messages
    478
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Non disponible

    Informations forums :
    Inscription : Décembre 2012
    Messages : 478
    Points : 877
    Points
    877
    Billets dans le blog
    1
    Par défaut
    Bonjour,

    C++11 permet le déplacement en utilisant la fonction emplace_back à la place de push_back.

  3. #3
    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 Merci de votre réponse, je reformule ma question
    Bonjour,
    Merci pour votre réponse. Je pense que je n'ai pas été assez clair car ce n'était pas ma question :

    Dans l'output, on voit (lors du troisième push-back ou du troisième emplace-back) que le vector ré-alloue son contenu pour s'agrandir, lorsqu'il le fait, on voit que ce sont les constructeurs de copie et non de déplacement qui sont appelés. Je ne comprend pas pourquoi.

    cette partie :
    constructing num3 from '' using move constructor
    constructing num2 from 'num2' using copy constructor
    constructing num1 from 'num1' using copy constructor

    Note : J'ai modifié mon main pour utilise emplace_back (c'est plus propre), mais l'output ne change pas.
    Voir :
    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
     
    int main(int argc, const char * argv[])
    {
        vector<Obj> vect;
     
        cout << endl << "first emplace back " << endl;
        vect.emplace_back(Obj("num1"));
     
        cout << endl << "second emplace back " << endl;
        vect.emplace_back(Obj("num2"));
     
     
        cout << endl << "third emplace back " << endl;
        vect.emplace_back(Obj("num3"));
     
        return 0;
    }
    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
     
    first emplace back 
    constructing num1{} rvalue
    constructing num1 from '' using move constructor
     
    second emplace back 
    constructing num2{} rvalue
    constructing num2 from '' using move constructor
    constructing num1 from 'num1' using copy constructor
     
    third emplace back 
    constructing num3{} rvalue
    constructing num3 from '' using move constructor
    constructing num2 from 'num2' using copy constructor
    constructing num1 from 'num1' using copy constructor

  4. #4
    En attente de confirmation mail

    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Août 2004
    Messages
    1 391
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 33
    Localisation : France, Doubs (Franche Comté)

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

    Informations forums :
    Inscription : Août 2004
    Messages : 1 391
    Points : 3 311
    Points
    3 311
    Par défaut
    Lorque move-ctor et copy-ctor existent, std::vector utilise le move-ctor uniquement ci celui-ci est noexcept, sinon il retombe sur le copy-ctor. Et la raison est d'assurer la résistance forte aux exceptions le plus souvent possible.

  5. #5
    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
    Merci !

  6. #6
    Membre émérite

    Inscrit en
    Mai 2008
    Messages
    1 014
    Détails du profil
    Informations forums :
    Inscription : Mai 2008
    Messages : 1 014
    Points : 2 252
    Points
    2 252
    Par défaut
    Citation Envoyé par n0-sheep Voir le message
    Note : J'ai modifié mon main pour utilise emplace_back (c'est plus propre), mais l'output ne change pas.
    Citation Envoyé par PilloBuenaGente Voir le message
    C++11 permet le déplacement en utilisant la fonction emplace_back à la place de push_back.
    Je ne comprends pas bien ce genre d'affirmation que j'ai vu flotter déjà plusieurs fois.

    emplace_back n'a pas été ajouté en C++11 pour permettre le déplacement , il permet la constuction d'objet sur place, directement en fin du vector, à partir d'argument utilisé par le constructeur :

    Le but premier d'emplace_back est de pouvoir faire :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
     
    struct A
    {
       A(int i, std::string s){}
    }
     
    vector<A> v;
    v.emplace_back(5, "toto");
    C'est vrai que le code suivant fonctionne aussi :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    v.emplace_back(A(5, "toto")
    mais c'est un effet de bord du à la signature d'emplace_back. En l'utilisant de cette manière on obscurcit l'intention vu qu'il n'y a justement pas de construction sur place mais un simple déplacement.

    Si l'on veut déplacer un objet dans un vector alors il vaut mieux utiliser push_back, qui est fait pour ça :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    v.push_back(A(5, "toto"));

  7. #7
    Membre éclairé

    Homme Profil pro
    Non disponible
    Inscrit en
    Décembre 2012
    Messages
    478
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Non disponible

    Informations forums :
    Inscription : Décembre 2012
    Messages : 478
    Points : 877
    Points
    877
    Billets dans le blog
    1
    Par défaut
    Ok, je ne peut pas m'auto-downer, quelqu'un peut, pour éviter d'induire en erreur ?!

    Le problème est sans doute tout autre, mais pourquoi puis-je remplir un vecteur avec des membres constant seulement avec emplace_back ?

    Merci !

  8. #8
    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
    Citation Envoyé par Arzar Voir le message
    emplace_back n'a pas été ajouté en C++11 pour permettre le déplacement , il permet la constuction d'objet sur place, directement en fin du vector, à partir d'argument utilisé par le constructeur [...]
    Merci pour la précision ! Je ne m'étais pas plongé dans les détails entre emplace et push, mais ca m'étonnait qu'il y ait une fonction spéciale déplacement alors qu'on peut le faire avec push.

    Citation Envoyé par PilloBuenaGente Voir le message
    Le problème est sans doute tout autre, mais pourquoi puis-je remplir un vecteur avec des membres constant seulement avec emplace_back ?

    Merci !
    A mon avis :
    Comme tu ne peux pas faire :
    Mais qu'il faut utiliser le constructeur pour initialiser un const :
    Eh bien ca marche pareil pour les éléments du vecteur, il faut utiliser directement le constructeur (appelé par emplace_back).

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. Réponses: 6
    Dernier message: 06/06/2013, 11h23
  2. Réponses: 4
    Dernier message: 04/06/2012, 15h19
  3. vertex array et std::vector marche pas, help!
    Par filoo dans le forum OpenGL
    Réponses: 14
    Dernier message: 07/07/2007, 13h00
  4. std ::vector [erreur que je ne comprend pas]
    Par aaronw dans le forum SL & STL
    Réponses: 8
    Dernier message: 05/03/2006, 21h00
  5. 3 précisions sur l'utilisation des "std::vector"
    Par Invité dans le forum SL & STL
    Réponses: 9
    Dernier message: 10/01/2006, 00h42

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