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 :

Surcharge opérateur std::vector


Sujet :

C++

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre averti
    Homme Profil pro
    CHercheur
    Inscrit en
    Août 2011
    Messages
    12
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : CHercheur
    Secteur : Industrie

    Informations forums :
    Inscription : Août 2011
    Messages : 12
    Par défaut Surcharge opérateur std::vector
    Bonjour à tous,

    Après de nombreuses recherches infructueuses sur le sujet (mauvais mots clefs?), je pose ici ma première question.

    Je cherche à réaliser la division et multiplication d'un std::vector par un double. Et je commence à devenir fou!

    Voici un code restreint qui... ne fonctionne pas.
    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
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
     
    #include <iostream>
    #include <vector>
     
    template< typename T>
    void show(std::vector< T > A)
    {
        for(std::size_t i = 0; i < A.size(); ++i) {
            std::cout << A[i] << std::endl;
        }
    }
     
    template< typename T>
    std::vector<T>& operator*(const T& a, std::vector<T> B)
    {
        for(std::size_t i = 0; i < B.size(); ++i) {
            B[i] = a*B[i];
        }
        return B;
    }
     
     
     
    int main()
    {
        std::cout << "Hello world!" << std::endl;
     
        std::vector<int> A(5), B;
     
        for(std::size_t i = 0; i < A.size(); ++i) {
            A[i] = (int)i;
        }
        std::cout << " A = " << std::endl;
        show(A);
        B = A;
        A = 5 * B;
     
        std::cout << " 5*A = " << std::endl;
        show(A);
     
        std::cout << " B = " << std::endl;
        show(B);
     
     
        return 0;
    }
    J'obtiens le bon résultat, mais le warning me semble dangereux.

    D:\vector_overload\main.cpp||In function 'std::vector<T>& operator*(const T&, std::vector<T>) [with T = int]'
    D:\vector_overload\main.cpp:35|13|instantiated from here|
    D:\vector_overload\main.cpp|13|warning: reference to local variable 'B' returned|
    ||=== Build finished: 0 errors, 1 warnings ===|
    Je suis sous code::blocks avec MINGW.

    J'essaie aussi de faire l'opérateur *=, mais c'est encore pire!

    Merci à tous.

  2. #2
    Membre expérimenté
    Profil pro
    Inscrit en
    Avril 2008
    Messages
    159
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2008
    Messages : 159
    Par défaut
    Hello,

    Ton warning :
    Ta fonction prend un paramètre B par valeur.
    Elle effectue donc une copie locale de B, modifie cette copie, et renvoie une référence sur cette copie locale.

    En sortie de fonction, ta copie locale de B est détruite et donc la référence renvoyée pointe vers... *kaboum* ?

    J'aurais plutôt vu un prototype de la forme
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    std::vector<T> operator*(const T& a, const std::vector<T>& B)
    Mais je peux me planter.

  3. #3
    Membre averti
    Homme Profil pro
    CHercheur
    Inscrit en
    Août 2011
    Messages
    12
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : CHercheur
    Secteur : Industrie

    Informations forums :
    Inscription : Août 2011
    Messages : 12
    Par défaut
    Oui c'est pour ça que je veux trouver le moyen de me débarrasser de ce warning. J'aurais bien aimé utiliser *this; mais je suis en dehors de la class.

    Citation Envoyé par valAa Voir le message

    J'aurais plutôt vu un prototype de la forme
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    std::vector<T> operator*(const T& a, const std::vector<T>& B)
    Mais je peux me planter.
    le & ne sert-il pas à rendre a et B modifiable par la fonction? Ce que je ne souhaite pas.

  4. #4
    Membre Expert
    Avatar de Joel F
    Homme Profil pro
    Chercheur en informatique
    Inscrit en
    Septembre 2002
    Messages
    918
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 45
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Chercheur en informatique
    Secteur : Service public

    Informations forums :
    Inscription : Septembre 2002
    Messages : 918
    Par défaut
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
     
    template<class > vector<T>
    operator*( double a, vector<T> const& b)
    {
      vector<T> tmp(b);
      for(size_t i=0;i<tmp.size();++i) tmp[i] *= a;
      return tmp;
    }

    - prendre les argument par reference constantes pour eviter les copies
    - les operateur libres renvoient de nouveaux vector pas des references a des temporaires.

  5. #5
    Expert éminent
    Avatar de koala01
    Homme Profil pro
    aucun
    Inscrit en
    Octobre 2004
    Messages
    11 635
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 53
    Localisation : Belgique

    Informations professionnelles :
    Activité : aucun

    Informations forums :
    Inscription : Octobre 2004
    Messages : 11 635
    Par défaut
    Salut,
    Citation Envoyé par boutor Voir le message
    le & ne sert-il pas à rendre a et B modifiable par la fonction? Ce que je ne souhaite pas.
    Le & sert à indiquer que l'on passe l'argument par référence, de manière à en éviter la copie (qui peut s'avérer extrêmement coûteuse)...

    Le fait est que, effectivement, lorsqu'un argument est passé par référence, les modifications que nous pourrions y apporter au sein de la fonction appelée seront répercutées dans l'objet originel de la fonction appelante.

    C'est la raison pour laquelle il y a lieu de fournir une référence constante, de manière à ce que le compilateur t'insulte dés que tu essaye de la modifier.

    Le passage d'une référence constante permet, en outre, de créer un temporaire anonyme qui n'existerait que pour la durée de l'appel de la fonction

    Tout cela pour en arriver à un conseil qu'il s'agit de suivre de manière quasi impérative : veille à respecter la "const correctness", c'est à dire à déclarer constant tout ce qui n'a pas vocation à être modifié ou qui n'a pas vocation à modifier l'objet au départ duquel tu appelle une fonction donnée.

    En effet, seules les fonctions membres déclarées constantes pourront être invoquées au départ des objets constants
    A méditer: La solution la plus simple est toujours la moins compliquée
    Ce qui se conçoit bien s'énonce clairement, et les mots pour le dire vous viennent aisément. Nicolas Boileau
    Compiler Gcc sous windows avec MinGW
    Coder efficacement en C++ : dans les bacs le 17 février 2014
    mon tout nouveau blog

  6. #6
    Membre averti
    Homme Profil pro
    CHercheur
    Inscrit en
    Août 2011
    Messages
    12
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : CHercheur
    Secteur : Industrie

    Informations forums :
    Inscription : Août 2011
    Messages : 12
    Par défaut
    Je progresse!

    Merci koala01 pour cette très bonne explication et Joël pour le bout de code.

    Dans le code j'en suis là :
    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
    34
    35
    36
    37
    38
    39
     
     
    #include <iostream>
    #include <vector>
     
    template< typename T>
    void show(std::vector< T > A)
    {
        for(std::size_t i = 0; i < A.size(); ++i) {
            std::cout << A[i] << std::endl;
        }
    }
     
     
    template< typename T, class > std::vector<T>
    operator*( T const& a, std::vector<T> const& b)
    {
        std::vector<int> tmp(b);
        for(size_t i=0;i<tmp.size();++i) tmp[i] *= a;
        return tmp;
    }
     
     
    int main()
    {
        std::vector<double> A(5), B;
        for(std::size_t i = 0; i < A.size(); ++i) {
            A[i] = (double)i;
        }
     
        std::cout << " A = " << std::endl;
        show(A);
        B = A;
        A = 5 * B;
     
        std::cout << " 5*A = " << std::endl;
        show(A);
        return 0;
    }
    Le compilateur ne semble toujours pas connaître l'opérateur:
    error: no match for 'operator*' in '5 * B'|

  7. #7
    Membre expérimenté
    Profil pro
    Inscrit en
    Avril 2008
    Messages
    159
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2008
    Messages : 159
    Par défaut
    Tu cherches à multiplier un int par un vecteur de double par (`5` sans autre précision est un int), alors que ton opérateur est prévu pour multiplier un T par un vector<T> (même type).

    De plus Il y a une erreur dans ton opérateur, tu déclares tmp comme un vector<int> au lieu d'un vector<T> (ton compilateur te parlera de cette erreur dès que tu auras résolu la première).

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

Discussions similaires

  1. Problème de surcharge d'opérateur std::cout
    Par Nyko17 dans le forum C++
    Réponses: 14
    Dernier message: 28/04/2008, 13h01
  2. Réponses: 3
    Dernier message: 04/12/2006, 13h01
  3. char[50] et std::vector<>
    Par tut dans le forum SL & STL
    Réponses: 9
    Dernier message: 12/10/2004, 13h26
  4. Réponses: 8
    Dernier message: 26/08/2004, 18h59
  5. Sauvegarde std::vector dans un .ini
    Par mick74 dans le forum MFC
    Réponses: 2
    Dernier message: 12/05/2004, 13h30

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