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 :

vecteur - erreur à l'initialisation


Sujet :

C++

  1. #1
    Membre du Club
    Profil pro
    Inscrit en
    Janvier 2008
    Messages
    89
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Janvier 2008
    Messages : 89
    Points : 50
    Points
    50
    Par défaut vecteur - erreur à l'initialisation
    Bonjour,

    Je rencontre le problème suivant et je n'arrive pas à savoir d'où ça vient. Ci dessous un extrait du 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
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
     
    class P
    {
       public:
          P(double aX, double aY):coord({aX,aY}) {};
     
          vector<double> getCoord() const;
          void init(const P &Pt);
     
       private:
         vector<double> coord;
    };
     
     
    vector<double> P::getCoord() const
    {
        return coord;
    }
     
     
     
    void P::init(const P &Pt)
    {
        vector<double> test({1.0,2.0}); //OK
        vector<double> test2(Pt.getCoord()); //OK
     
        coord.swap(test); //OK
        coord.swap(test2); //OK
     
        // coord(test); //error: no match for call to '(std::vector<double>) (std::vector<double>&)'|
        // coord(Pt.getCoord()); //error: no match for call to '(std::vector<double>) (std::vector<double>)': 
        // coord.swap(Pt.getCoord()); //error: no matching function for call to std::vector<double>::swap(std::vector<double>)'
    }
    Pourtant, on doit pouvoir initialiser un vecteur à partir d'un autre (cf http://www.cplusplus.com/reference/v...vector/vector/)

    Christian

  2. #2
    Membre expérimenté

    Homme Profil pro
    Étudiant
    Inscrit en
    Novembre 2011
    Messages
    685
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Ain (Rhône Alpes)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Novembre 2011
    Messages : 685
    Points : 1 418
    Points
    1 418
    Par défaut
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
     
    // coord(test); //error: no match for call to '(std::vector<double>) (std::vector<double>&)'|
        // coord(Pt.getCoord()); //error: no match for call to '(std::vector<double>) (std::vector<double>)': 
        // coord.swap(Pt.getCoord()); //error: no matching function for call to std::vector<double>::swap(std::vector<double>)'
    }
    coord n'est pas un type mais une instance. Pour la dernière erreur modifie le type de retour de getCoord avec une référence sur ton type de retour plutôt qu'une copie
    Nullius in verba

  3. #3
    Membre du Club
    Profil pro
    Inscrit en
    Janvier 2008
    Messages
    89
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Janvier 2008
    Messages : 89
    Points : 50
    Points
    50
    Par défaut
    Merci Kaamui pour ta réponse ... mais je ne saisi pas ce que tu veux dire par "coord n'est pas un type mais une instance". Peux-tu être plus explicite ?

  4. #4
    Membre expérimenté Avatar de Trademark
    Profil pro
    Inscrit en
    Février 2009
    Messages
    762
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2009
    Messages : 762
    Points : 1 396
    Points
    1 396
    Par défaut
    Cette syntaxe là : coord(test) sur un objet (ici coord de type std::vector<double>) fait appel à l'opérateur() de cet objet, or il n'est pas définit pour le type vector. Si tu veux réinitialiser ton objet, tu peux faire ça :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    coord = std::vector<double>(Pt.getCoord());
    Ensuite ton swap marcherait si tu renvoyais une référence de ton membre, mais de toute manière swap n'est pas l'opération qui t'intéresse vu que ça va aussi modifier l'argument passé à init. Par contre il vaut mieux que tu renvois une ref constante là :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    const vector<double>& getCoord() const;
    De manière plus général je pense que tu te plantes en créant une méthode init, utilise le constructeur ou remplace la valeur à plus haut niveau (la classe std::vector, comme tu as pu le constater ne propose pas de mécanismes "init" et pourtant on s'en sort bien sans). Ce qui donnerait à l'utilisation :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
     
    P pt(1, 2);
    // Au lieu de 
    pt.init(P(3, 4));
    // Faire 
    pt = P(3, 4);

  5. #5
    Membre expérimenté

    Homme Profil pro
    Étudiant
    Inscrit en
    Novembre 2011
    Messages
    685
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Ain (Rhône Alpes)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Novembre 2011
    Messages : 685
    Points : 1 418
    Points
    1 418
    Par défaut
    Citation Envoyé par coberle Voir le message
    Merci Kaamui pour ta réponse ... mais je ne saisi pas ce que tu veux dire par "coord n'est pas un type mais une instance". Peux-tu être plus explicite ?

    Je voulais dire que ton écriture n'est pas valable pour ce que tu essayais de faire. Tu as défini une variable nommée coord de Type (class) A. Tu essaies ensuite d'appeler (j'ai l'impression) un constructeur par copie.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
     
    //la bonne syntaxe
    Type Instance = Type(InstanceACopier) // Ici, Type() avec en paramètre une instance de type Type, est un constructeur par copie
     
    //ta syntaxe
    Instance(InstanceACopier) //Ici, tu n’appelles pas un constructeur par copie, mais l'opérateur () de la classe Type avec en paramètre (une référence vers) une instance de classe Type
    Suis les conseils de Trademark
    Nullius in verba

  6. #6
    Membre du Club
    Profil pro
    Inscrit en
    Janvier 2008
    Messages
    89
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Janvier 2008
    Messages : 89
    Points : 50
    Points
    50
    Par défaut
    Merci Kaamui et Trademark pour votre répons et conseils. Got it (j'espère) !

  7. #7
    Rédacteur/Modérateur
    Avatar de JolyLoic
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Août 2004
    Messages
    5 463
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 49
    Localisation : France, Yvelines (Île de France)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Août 2004
    Messages : 5 463
    Points : 16 213
    Points
    16 213
    Par défaut
    Je pense que le mieux est quand même d’initialiser tes données dans la liste d'initialisation du constructeur (pas de fonction init, c'est un mauvais signe qu'il y en ait une !!)

    http://cpp.developpez.com/faq/cpp/?p...-l-affectation
    Ma session aux Microsoft TechDays 2013 : Développer en natif avec C++11.
    Celle des Microsoft TechDays 2014 : Bonnes pratiques pour apprivoiser le C++11 avec Visual C++
    Et celle des Microsoft TechDays 2015 : Visual C++ 2015 : voyage à la découverte d'un nouveau monde
    Je donne des formations au C++ en entreprise, n'hésitez pas à me contacter.

  8. #8
    Membre éprouvé
    Profil pro
    Inscrit en
    Mars 2010
    Messages
    309
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mars 2010
    Messages : 309
    Points : 928
    Points
    928
    Par défaut
    Citation Envoyé par Kaamui Voir le message
    Je voulais dire que ton écriture n'est pas valable pour ce que tu essayais de faire. Tu as défini une variable nommée coord de Type (class) A. Tu essaies ensuite d'appeler (j'ai l'impression) un constructeur par copie.
    Le probleme est qu'il utilise la syntaxe d'initialisation
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
     vector<double> vect2(vect1);
    pour l'affectation.
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    vector<double> vect2;
    vect2(vect1); // INCORRECT! C'est un appel de "fonction", ca ne marche pas sur les vecteurs.
    La syntaxe avec parenthese n'est valable qu'a l'initialisation d'une variable. Et oui, dans un constructeur, la syntaxe avec parenthese est loin du type de la variable, mais c'est quand meme une initialisation:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    class Foo {
     public:
       Foo(const vector<double>& vect) : content_(vect) {}
     private:
       vector<double> content_;
    }

  9. #9
    Membre expérimenté

    Homme Profil pro
    Étudiant
    Inscrit en
    Novembre 2011
    Messages
    685
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Ain (Rhône Alpes)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Novembre 2011
    Messages : 685
    Points : 1 418
    Points
    1 418
    Par défaut
    ça ne marche pas justement parce que la classe vector n'implémente pas l'opérateur () : std::vector

    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
     
    #include <iostream>
    #include <vector>
     
    using namespace std;
     
    class Foo
    {
        public:
     
            vector<double> operator()(vector<double>& src)
            {
                return src;
            }
    };
     
    int main()
    {
        vector<double> vect1 = {1, 2, 3};
        Foo vect2;
        vect2(vect1);
        return 0;
    }
    La "syntaxe avec parenthèse" est un constructeur par copie, ce qui explique qu'elle ne soit utilisable qu'à l'instanciation. Mais comme montré avec le code ci dessus, son code aurait très bien pu être valable par le biais d'une autre "syntaxe avec parenthèse". Le code ci-dessus compile.
    Nullius in verba

  10. #10
    Expert éminent sénior

    Femme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Juin 2007
    Messages
    5 189
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Localisation : France, Essonne (Île de France)

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

    Informations forums :
    Inscription : Juin 2007
    Messages : 5 189
    Points : 17 141
    Points
    17 141
    Par défaut
    La construction par copie est uniquement accessible dans une déclaration type variable(autre_variable);, ou un pasage d'argument sans référence.
    Sinon (variable(autre_variable);), c'est l'appel à operator().

    C'est très différent.
    Mes principes de bases du codeur qui veut pouvoir dormir:
    • Une variable de moins est une source d'erreur en moins.
    • Un pointeur de moins est une montagne d'erreurs en moins.
    • Un copier-coller, ça doit se justifier... Deux, c'est un de trop.
    • jamais signifie "sauf si j'ai passé trois jours à prouver que je peux".
    • La plus sotte des questions est celle qu'on ne pose pas.
    Pour faire des graphes, essayez yEd.
    le ter nel est le titre porté par un de mes personnages de jeu de rôle

  11. #11
    Membre expérimenté

    Homme Profil pro
    Étudiant
    Inscrit en
    Novembre 2011
    Messages
    685
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Ain (Rhône Alpes)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Novembre 2011
    Messages : 685
    Points : 1 418
    Points
    1 418
    Par défaut
    C'est exactement ce que j'ai dit.
    Nullius in verba

  12. #12
    Expert éminent sénior

    Femme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Juin 2007
    Messages
    5 189
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Localisation : France, Essonne (Île de France)

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

    Informations forums :
    Inscription : Juin 2007
    Messages : 5 189
    Points : 17 141
    Points
    17 141
    Par défaut
    Je ne l'avais pas compris.
    Heureux d'être d'accord, en ce cas.
    Mes principes de bases du codeur qui veut pouvoir dormir:
    • Une variable de moins est une source d'erreur en moins.
    • Un pointeur de moins est une montagne d'erreurs en moins.
    • Un copier-coller, ça doit se justifier... Deux, c'est un de trop.
    • jamais signifie "sauf si j'ai passé trois jours à prouver que je peux".
    • La plus sotte des questions est celle qu'on ne pose pas.
    Pour faire des graphes, essayez yEd.
    le ter nel est le titre porté par un de mes personnages de jeu de rôle

Discussions similaires

  1. Erreur d'initialisation de requête - option RTF
    Par verticka dans le forum WinDev
    Réponses: 2
    Dernier message: 25/11/2005, 09h55
  2. Réponses: 1
    Dernier message: 13/07/2005, 15h51
  3. [BDE Errors] Erreur d'initialisation
    Par SubZero2 dans le forum Bases de données
    Réponses: 2
    Dernier message: 13/07/2005, 08h46
  4. Erreur d'initialisation du BDE sous Delphi7 ent et WinXP
    Par touhami dans le forum Bases de données
    Réponses: 1
    Dernier message: 15/02/2005, 01h51
  5. [Tomcat MySQL] Erreur d'initialisation d'un pool
    Par mmed dans le forum Eclipse Java
    Réponses: 2
    Dernier message: 05/01/2005, 09h22

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