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 :

Probleme avec les templates


Sujet :

C++

  1. #1
    Membre averti
    Profil pro
    Inscrit en
    Juillet 2004
    Messages
    410
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juillet 2004
    Messages : 410
    Points : 361
    Points
    361
    Par défaut Probleme avec les templates
    Salut,
    en ce moment je suis entrain de me frapper les templates pour apprendre.
    Bon le but du jeu (celui que je me suis fixé) est de faire un class MATRIX (le truc très classique quoi. Seulement j'ai quelques soucis avec le constructeur de recopie et l'opérateur d'affectation. J'aimerais faire dans un premier temps des classes MATRIX<T> avec T soit int, float ou double. Pour le moment ça fonctionne presque mais pas le constructeur de recopie ni l'opérateur d'affectation:

    matrix.h
    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
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
     
    // #include blablabla...
     
    template<class T>
    class MATRIX
    {
    private:
        size_t nl;
        size_t nc;
        T** tab;
     
    public:
        //Constructors
     
        MATRIX();
     
        MATRIX(const size_t& li,const size_t& co,const T& val=T());
     
        template<class U>
        MATRIX(const MATRIX<U>& mat); // je voudrais etre capable d'accepter des matrices d'un template à l'autre (ex dans le main.cpp).
     
        //Destructor
        ~MATRIX(){ Reset();}
     
        // Operators
        template<class U>
        MATRIX<T>& operator=(const MATRIX<U>& mat);  // idem mais ça ne marche pas
        T& operator()(const size_t& i, const size_t& j);
        const T& operator()(const size_t& i,const size_t& j) const;    
        // les autres operatoeurs +*/-... sont pas encores implementes
     
     
        template<class U>
        friend std::ostream &operator<<(std::ostream &out,MATRIX<U> &mat);
        void Print(std::ostream& out) const;
     
        inline const size_t& Line() const{return nl;}
        inline const size_t& Column() const{return nc;}
     
        bool Allocate(const size_t& li,const size_t& co);
        void Reset();
     
        template<class U>
        void Initialize(const U& val);
     
        MATRIX<T>& Transpose(); 
    }
     
    ...
     
    template<class T>
    template<class U>
    MATRIX<T>::MATRIX(const MATRIX<U>& mat)
    {
        tab=(T**)NULL;
     
        if(!Allocate(mat.Line(),mat.Column()))
            std::cout<<"Can not allocate memory!"<<std::endl;
     
        std::cout<<"Dans le constructeur de recopie"<<std::endl;
        for(size_t i=0;i<nl;++i)
            for(size_t j=0;j<nc;++j)
                tab[i][j]=(T)(mat(i,j));
    }
     
    ...
     
    template<class T>
        template<class U>
    MATRIX<T>& MATRIX<T>::operator=(const MATRIX<U>& mat)
    {
        if(this!=&mat) // plante à la compilation (voir main.cpp)
        {
            Reset();
            Allocate(mat.Line(),mat.Column());
     
            for(size_t i=0;i<nl;++i)
                for(size_t j=0;j<nc;++j)
                    tab[i][j]=static_cast<T> (mat(i,j));
        }
     
        return *this;
    }
     
    ...
     
    template<class T>
    MATRIX<T>& MATRIX<T>::Transpose()
    {
        MATRIX<T> tmp(*this);  // ICI l'operateur de recopie n'est pas appelé ??
     
        Reset();
        Allocate(tmp.Column(),tmp.Line());
     
        for(size_t i=0;i<nl;++i)
            for(size_t j=0;j<nc;++j)
                tab[i][j]=tmp(j,i);
     
        return *this;
    }
    test avec le main.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
     
    int main(int argc,char** argv)
    {
        int size=3;
        MATRIX<double> A(size,size);
     
        A.Initialize(M_PI);
     
        cout<<A;   // Affiche bien une matrice 3x3 avec 3.14.. dedans
     
        MATRIX<int> B(A);  // Fonctionne tres bien !
     
        cout<<B;  // Affiche 3 dans une matrice 3x3
     
    //    B=A;   // Plante à la compile comparaison     if(this!=&mat) marche pas
     
        A.Transpose(); // Plante à l'execution car dans la methode Transpose tmp n'est pas construit (j'ai pas le message du constructeur de recopie)
     
        cout<<A;
    }
    voila j'espere que je suis clair
    Merci d'avancepour votre aide.

    Sinon j'aimerais à terme étendre ma classe à la classe complexe, faire un truc du style MATRIX<complex<double>>, est ce que vous avec des pistes?
    Merci d'avance encore

  2. #2
    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
    Citation Envoyé par reptils Voir le message
    Seulement j'ai quelques soucis avec le constructeur de recopie et l'opérateur d'affectation.
    Un constructeur de copie ou un opératuer d'affectation ne peuvent pas être des templates.
    Citation Envoyé par La norme
    A nontemplate constructor for class X is a copy constructor if its first parameter is of type X&, const X&, volatile X& or const volatile X&, and either there are no other parameters or else all other parameters have default arguments (8.3.6).106)
    __________________
    106) Because a template constructor is never a copy constructor, the presence of such a template does not suppress the implicit declaration of a copy constructor. Template constructors participate in overload resolution with other constructors, including copy constructors, and a template constructor may be used to copy an object if it provides a better match than other constructors.
    Donc tu dois aussi définir une version non template pour le cas où le type est le même.

    Citation Envoyé par reptils Voir le message
    Sinon j'aimerais à terme étendre ma classe à la classe complexe, faire un truc du style MATRIX<complex<double>>, est ce que vous avec des pistes?
    Merci d'avance encore
    Bin, MATRIX<complex<double> >, non ? (penser à l'espace entre les >, sinon le token est interprété comme un seul token >> au lieu de 2 tokens >)
    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.

  3. #3
    Membre averti
    Profil pro
    Inscrit en
    Juillet 2004
    Messages
    410
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juillet 2004
    Messages : 410
    Points : 361
    Points
    361
    Par défaut
    Super tu as raison !!!
    j'ai redefini en plus l'operateur d'affectation et le constructeur de recopie pour le meme template et ça fonctionne.
    De meme pour le coup du >> qui était reconnu comme un operateur. Maintentant je peux utiliser aussi les complex.

    En fait je ne comprend pas un truc, je me suis inspiré du header de mingw (complex) pour voir omment était géré les templates. Et le seul constructeur de recopie qui est défini est :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    template<typename _Tp>
    class complex
    {
        public:
    ...
        // Lets the compiler synthesize the copy constructor   
        // complex (const complex<_Tp>&);
        ///  Copy constructor.
        template<typename _Up>
        complex(const complex<_Up>&);
    ...
    }
    Je suppose que ce qui est en commentaire signifie qu'il laisse le soin au compilateur de gerer les recopie avec _Tp normale...
    bref en tout cas je garde ta solution sous le coude.

    Merci encore

    EDIT: encore une question, dans le cours C++ de christian casteyde sur les template, il dit qu'on peut "exporter" les fonctions template comme ça on peut les definir dans des fichiers séparés, et une petite note précise qu'aucun compilateur ne gérait export pour les templates à ce jour. Est ce normale?

  4. #4
    Membre éprouvé
    Avatar de NiamorH
    Inscrit en
    Juin 2002
    Messages
    1 309
    Détails du profil
    Informations forums :
    Inscription : Juin 2002
    Messages : 1 309
    Points : 1 051
    Points
    1 051
    Par défaut
    Citation Envoyé par reptils Voir le message
    EDIT: encore une question, dans le cours de christian casteyde sur les template, il dit qu'on peut "exporter" les fonctions template comme ça on peut les definir dans des fichiers séparés, et une petite note précise qu'aucun compilateur ne gérait export pour les templates à ce jour. Est ce normale?
    Salut,
    tout d'abord je ne sais pas de quand date ce cours ni ce qu'il en est maintenant. En fin 2002, ce que tu dis etait vrai en tout cas.

    S'il est vrai que ce mécanisme permet de séparer déclarations et définitions et de cacher l'implémentation de ton template lors de la création d'une bibliotheque, il présente malgré tout des inconvénients.

    Deux cpp sont sencés ne pas être couplés (mis à part inclusion éventuelle), c'est à dire que la modif de l'un ne doit pas nécessiter la recompil de l'autre.
    Pourtant dans le cas d'un export de template, il y a un couplage qui est fait : Si tu modifies le cpp du template exporté, il faudra recompiler le cpp qui inclut pourtant seulement le .h.
    Mais voilà, il y a un risque que les outils de contrôle de dépendances ne détectent pas ce couplage et ne recompilent pas ton cpp appellant. Cela ne devrait pas générer d'erreur de compilation ou de link (et encore, ça je ne suis pas sur de moi) mais tu continueras à éxécuter ton ancien code sans savoir pourquoi.

    Si tu fais une bibliotheque qui utilise l'export de template, je ne sais pas si le compilateur de l'utilisateur de la bibli ne doit pas aussi pouvoir gérer ce mécanisme ? Si il y a toujours aussi peu de compilateurs qui le prennent en charge, ca réduit le nombre éventuel d'utilisateurs de ta bibli.

  5. #5
    Expert confirmé
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Décembre 2003
    Messages
    3 549
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Essonne (Île de France)

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

    Informations forums :
    Inscription : Décembre 2003
    Messages : 3 549
    Points : 4 625
    Points
    4 625
    Par défaut
    Bon le but du jeu (celui que je me suis fixé) est de faire un class MATRIX
    Les noms en capitales comme ceci sont plutôt déconseillés.
    Boost ftw

  6. #6
    Membre averti
    Profil pro
    Inscrit en
    Juillet 2004
    Messages
    410
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juillet 2004
    Messages : 410
    Points : 361
    Points
    361
    Par défaut
    Citation Envoyé par NiamorH Voir le message
    Salut,
    tout d'abord je ne sais pas de quand date ce cours ni ce qu'il en est maintenant. En fin 2002, ce que tu dis etait vrai en tout cas.
    ben il est censé etre mis à jour depuis cette année... p'etre que tout n'est pas mis à jour

    Citation Envoyé par NiamorH Voir le message
    S'il est vrai
    ...
    mais tu continueras à éxécuter ton ancien code sans savoir pourquoi.
    ok

    Citation Envoyé par NiamorH Voir le message
    Si tu fais une bibliotheque qui utilise l'export de template, je ne sais pas si le compilateur de l'utilisateur de la bibli ne doit pas aussi pouvoir gérer ce mécanisme ? Si il y a toujours aussi peu de compilateurs qui le prennent en charge, ca réduit le nombre éventuel d'utilisateurs de ta bibli.
    Je n'ai pas l'intention de faire une bibliotheque, c'est juste pour m'amuser pour apprendre à manipuler les templates/operateurs... . En fait j'ai décider de mettre vraiment au C++, car jusqu'à present je faisais plutot une mixture C/C++ je prenais les composants de l'un et l'autre comme ça m'arrangeais etc... . Bref! j'aimerais arreter de faire du bricolage et faire les choses dans les regles, si c'est possible en pure C++. Suite de mon apprentissage, la stl puis boost.

    il ya à ce sujet NT² pour les templates de matrice http://nt2.sourceforge.net/

    Citation Envoyé par loufoque Voir le message
    Les noms en capitales comme ceci sont plutôt déconseillés.
    ah ouais ... zit tous mes codes sont comme ça, nom des structures et class en majuscule

    Ah encore une question (toujours sur les templates)
    j'utilise mingw, et j'ai cherché comment faire (option de compil) pour utiliser ques les instanciations explicites des templates histoire qu'on ne fasse pas un truc du genre MATRIX<cheval>, mais j'ai pas trouvé. C'est dans les options de compilation qu'on peut imposer la restriction aux instanciations explicites? ou bien le fait d'en definir fait que le compilo prendra que les eplicite?

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

Discussions similaires

  1. probleme avec les templates
    Par vamos dans le forum Débuter
    Réponses: 2
    Dernier message: 24/10/2009, 14h41
  2. wpf: probleme avec les templates
    Par mk.wassim dans le forum Windows Presentation Foundation
    Réponses: 3
    Dernier message: 18/03/2009, 17h54
  3. Probleme Avec les templates
    Par dot-_-net dans le forum C++
    Réponses: 1
    Dernier message: 28/01/2009, 21h35
  4. probleme avec les templates d'un formview
    Par devdotnet dans le forum ASP.NET
    Réponses: 2
    Dernier message: 01/11/2007, 09h32
  5. Probleme avec les templates
    Par TeC_MaN dans le forum C++
    Réponses: 2
    Dernier message: 08/01/2006, 14h53

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