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 :

Opérateur template "undefined"


Sujet :

Langage C++

  1. #1
    Membre averti
    Profil pro
    Inscrit en
    Août 2007
    Messages
    27
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Août 2007
    Messages : 27
    Par défaut Opérateur template "undefined"
    Bonjour !

    A l'occasion d'un programme utilisant le calcul matriciel, j'ai découvert l'utilisation des templates.
    J'ai créé une classe CMatrix dont voici le header :
    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
    #ifndef MATRIX_H
       #define MATRIX_H
     
       #include <iostream>
     
       using namespace std;
     
       template <class type>
       class CMatrix
       {
          protected:
     
          unsigned int
             height,
             width;
          type* table;
     
          public:
     
          CMatrix() : height(0), width(0), table(NULL) {};
          CMatrix(const CMatrix<type>&);
          CMatrix(const unsigned int, const unsigned int, const type* newTable);
          ~CMatrix();
     
          void set(const unsigned int, const unsigned int, const type* newTable = NULL);
          void set(const unsigned int, const unsigned int, const type);
          void reset();
     
          unsigned int getHeight() const;
          unsigned int getWidth() const;
     
          template <class T>
          friend CMatrix<T> operator+(const CMatrix<T>&, const CMatrix<T>&);
          template <class T>
          friend CMatrix<T> operator*(const CMatrix<T>&, const CMatrix<T>&);
     
          CMatrix<type> operator=(const CMatrix<type>&);
          type          operator()(const unsigned int, const unsigned int column = 0) const;
       };
     
     
     
       #include "CMatrix.tpp"
     
    #endif
    Du fait de l'utilisation de templates, j'ai dû inclure l'implémentation de cette classe dans le header, comme expliqué dans la FAQ de ce site.
    J'attire votre attention sur l'opérateur multiplicatif, dont voici l'implémentation :
    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
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    template <class T>
    CMatrix<T> operator*(const CMatrix<T>& matrix1, const CMatrix<T>& matrix2)
    {
       if (matrix1.getWidth() == matrix2.getHeight())
       {
          unsigned int i = 0, j = 0, k = 0;
          T*        temp = new T[matrix1.getHeight() * matrix2.getWidth()];
     
          i = 0;
          while (i < matrix1.getHeight())
          {
             while (j < matrix2.getWidth())
             {
                temp[i*matrix2.getWidth() + j] = 0;
     
                while (k < matrix1.getWidth())
                {
                   temp[i*matrix2.getWidth() + j] += matrix1(i, k) * matrix2(k, j);
                   k++;
                }
     
                k = 0;
                j++;
             }
     
             j = 0;
             i++;
          }
     
          CMatrix<T> result(matrix1.getHeight(), matrix2.getWidth(), temp);
     
          delete[] temp;
     
          return result;
       }
     
       return CMatrix<T>();
    }
     
    template <>
    CMatrix<bool> operator*(const CMatrix<bool>& matrix1, const CMatrix<bool>& matrix2)
    {
       if (matrix1.getWidth() == matrix2.getHeight())
       {
          unsigned int i = 0, j = 0, k = 0;
          bool*        temp = new bool[matrix1.getHeight() * matrix2.getWidth()];
     
          i = 0;
          while (i < matrix1.getHeight())
          {
             while (j < matrix2.getWidth())
             {
                temp[i*matrix2.getWidth() + j] = 0;
     
                while (k < matrix1.getWidth())
                {
                   if (matrix1(i, k) | matrix2(k, j))
                   {
                      temp[i*matrix2.getWidth() + j] = !temp[i*matrix2.getWidth() + j];
                   }
                   k++;
                }
     
                k = 0;
                j++;
             }
     
             j = 0;
             i++;
          }
     
          CMatrix<bool> result(matrix1.getHeight(), matrix2.getWidth(), temp);
     
          delete[] temp;
     
          return result;
       }
     
       return CMatrix<bool>();
    }
    Etant donné que c'est la première fois que j'utilise les templates, je ne suis pas très à l'aise avec et ai dû faire sans doute des erreurs de débutants. J'en viens donc à mon problème : la compilation échoue et les erreurs suivantes me sont retournées :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    Main.o: In function `CMatrix<bool> operator*<bool>(CMatrix<bool> const&, CMatrix<bool> const&)':
    Main.cpp:(.text+0xfa): multiple definition of `CMatrix<bool> operator*<bool>(CMatrix<bool> const&, CMatrix<bool> const&)'
    CWord.o:CWord.cpp:(.text+0x988): first defined here
    CWord.o: In function `operator*(CMatrix<bool> const&, CWord const&)':
    CWord.cpp:(.text+0xcb9): undefined reference to `operator*(CMatrix<bool> const&, CMatrix<bool> const&)'
    CWord.o: In function `operator*(CWord const&, CWord const&)':
    CWord.cpp:(.text+0xd40): undefined reference to `operator*(CMatrix<bool> const&, CMatrix<bool> const&)'
    Visiblement, le compilateur n'a pas reconnu ma spécialisation, et prétend que l'opérateur multiplicatif n'est pas défini... Je ne serai pas étonné que cela soit dû à une mauvaise utilisation des templates, en tout cas je ne parviens pas seul à corriger cette erreur. Pourriez-vous m'expliquer comment ?

    Merci d'avance !

  2. #2
    Membre Expert
    Avatar de coyotte507
    Profil pro
    Inscrit en
    Octobre 2006
    Messages
    1 327
    Détails du profil
    Informations personnelles :
    Âge : 34
    Localisation : France

    Informations forums :
    Inscription : Octobre 2006
    Messages : 1 327
    Par défaut
    Salut,

    je ne sais pas si c'est le cas dans ton code, mais les définitions des fonctions template doivent tout le temps se retrouver d'une façon ou d'une autre dans le header, alors que les autres fonctions de classes peuvent n'être définies que dans les cpp...

  3. #3
    Membre averti
    Profil pro
    Inscrit en
    Août 2007
    Messages
    27
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Août 2007
    Messages : 27
    Par défaut
    C'est le cas dans mon code, j'ai inclus un fichier .tpp, qui contient les définitions, dans le header.

  4. #4
    Membre Expert
    Avatar de coyotte507
    Profil pro
    Inscrit en
    Octobre 2006
    Messages
    1 327
    Détails du profil
    Informations personnelles :
    Âge : 34
    Localisation : France

    Informations forums :
    Inscription : Octobre 2006
    Messages : 1 327
    Par défaut
    Ca marche quand je met cette partie:

    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
    template <>
    CMatrix<bool> operator*(const CMatrix<bool>& matrix1, const CMatrix<bool>& matrix2)
    {
       if (matrix1.getWidth() == matrix2.getHeight())
       {
          unsigned int i = 0, j = 0, k = 0;
          bool*        temp = new bool[matrix1.getHeight() * matrix2.getWidth()];
     
          i = 0;
          while (i < matrix1.getHeight())
          {
             while (j < matrix2.getWidth())
             {
                temp[i*matrix2.getWidth() + j] = 0;
     
                while (k < matrix1.getWidth())
                {
                   if (matrix1(i, k) | matrix2(k, j))
                   {
                      temp[i*matrix2.getWidth() + j] = !temp[i*matrix2.getWidth() + j];
                   }
                   k++;
                }
     
                k = 0;
                j++;
             }
     
             j = 0;
             i++;
          }
     
          CMatrix<bool> result(matrix1.getHeight(), matrix2.getWidth(), temp);
     
          delete[] temp;
     
          return result;
       }
     
       return CMatrix<bool>();
    }
    Dans le cpp.

  5. #5
    Membre averti
    Profil pro
    Inscrit en
    Août 2007
    Messages
    27
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Août 2007
    Messages : 27
    Par défaut
    Chez moi disparaît l'erreur de multiple définition, demeurent les erreurs de "undefined reference". Merci déjà pour ce petit pas !

  6. #6
    Membre Expert
    Avatar de coyotte507
    Profil pro
    Inscrit en
    Octobre 2006
    Messages
    1 327
    Détails du profil
    Informations personnelles :
    Âge : 34
    Localisation : France

    Informations forums :
    Inscription : Octobre 2006
    Messages : 1 327
    Par défaut
    Salut,

    désolé encore pour ne pas avoir résolu directement.

    Chez moi je met ça dans le cpp:

    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
    CMatrix<bool> operator*(const CMatrix<bool>& matrix1, const CMatrix<bool>& matrix2)
    {
       if (matrix1.getWidth() == matrix2.getHeight())
       {
          unsigned int i = 0, j = 0, k = 0;
          bool*        temp = new bool[matrix1.getHeight() * matrix2.getWidth()];
     
          i = 0;
          while (i < matrix1.getHeight())
          {
             while (j < matrix2.getWidth())
             {
                temp[i*matrix2.getWidth() + j] = 0;
     
                while (k < matrix1.getWidth())
                {
                   if (matrix1(i, k) | matrix2(k, j))
                   {
                      temp[i*matrix2.getWidth() + j] = !temp[i*matrix2.getWidth() + j];
                   }
                   k++;
                }
     
                k = 0;
                j++;
             }
     
             j = 0;
             i++;
          }
     
          CMatrix<bool> result(matrix1.getHeight(), matrix2.getWidth(), temp);
     
          delete[] temp;
     
          return result;
       }
     
       return CMatrix<bool>();
    }
    Mais en enlevent le template<> qui est inutile car il n'y a rien à l'intérieur.

    Par contre, cette partie 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
    template <class T>
    CMatrix<T> operator*(const CMatrix<T>& matrix1, const CMatrix<T>& matrix2)
    {
       if (matrix1.getWidth() == matrix2.getHeight())
       {
          unsigned int i = 0, j = 0, k = 0;
          T*        temp = new T[matrix1.getHeight() * matrix2.getWidth()];
     
          i = 0;
          while (i < matrix1.getHeight())
          {
             while (j < matrix2.getWidth())
             {
                temp[i*matrix2.getWidth() + j] = 0;
     
                while (k < matrix1.getWidth())
                {
                   temp[i*matrix2.getWidth() + j] += matrix1(i, k) * matrix2(k, j);
                   k++;
                }
     
                k = 0;
                j++;
             }
     
             j = 0;
             i++;
          }
     
          CMatrix<T> result(matrix1.getHeight(), matrix2.getWidth(), temp);
     
          delete[] temp;
     
          return result;
       }
     
       return CMatrix<T>();
    }
    Je la laisse dans le tpp...

    J'utilise MinGW (équivalent de GCC)

  7. #7
    Membre averti
    Profil pro
    Inscrit en
    Août 2007
    Messages
    27
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Août 2007
    Messages : 27
    Par défaut
    Merci beaucoup pour la dernière précision, je n'ai plus d'erreur.
    Sujet clos.

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

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