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 de template dans un fichier .cpp


Sujet :

C++

  1. #1
    Membre confirmé
    Homme Profil pro
    Étudiant
    Inscrit en
    Juillet 2013
    Messages
    70
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Juillet 2013
    Messages : 70
    Par défaut Probleme de template dans un fichier .cpp
    Bonjour,

    j'ai un problème avec ces deux morceaux de codes:
    C'est à dire que quand je compile il me dit qu'il y'a une erreur
    dans le .cpp, il ne connait pas le " T " et il y'a une utilisation invalide
    du template.

    Je vous remercie d'avance pour votre aide !

    Rq: Forme.h est la classe mère de Cercle

    Cercle.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
     
    #include <iostream>
    #include <string>
     
    #include "Cercle.h"
     
    using namespace std;
     
    template<typename T>
    Cercle::Cercle(T p_rayon,string p_nom): rayon(p_rayon),Forme(p_nom)
    {}
     
    T Cercle:: getRayon(){
    return rayon;
    }
    Cercle.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
     
    #ifndef DEF_CERCLE
    #define DEF_CERCLE
     
    #include<string>
    #include "Forme.h"
     
     
    using namespace std;
     
    template<typename T=int>//template par défaut = int
    class Cercle : public Forme
    {
    public:
     
        Cercle(T p_rayon,string p_nom);
     
        T getRayon();
     
     
    private:
     
        T rayon;
     
     
    };
     
    #endif

  2. #2
    Rédacteur/Modérateur


    Homme Profil pro
    Network game programmer
    Inscrit en
    Juin 2010
    Messages
    7 147
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 37
    Localisation : Canada

    Informations professionnelles :
    Activité : Network game programmer

    Informations forums :
    Inscription : Juin 2010
    Messages : 7 147
    Billets dans le blog
    4
    Par défaut
    Salut,

    un template ça s'implémente dans un header.
    http://cpp.developpez.com/faq/cpp/?p...tion-des-liens
    Pensez à consulter la FAQ ou les cours et tutoriels de la section C++.
    Un peu de programmation réseau ?
    Aucune aide via MP ne sera dispensée. Merci d'utiliser les forums prévus à cet effet.

  3. #3
    Membre émérite

    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
    Billets dans le blog
    1
    Par défaut
    Bonjour,

    Le template, si il est utilisé dans un fichier cpp, doit être définit.

    Deux options :

    Tout définir dans le .h
    .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
    #ifndef DEF_CERCLE
    #define DEF_CERCLE
    //==============================================================================
    #include <string>
    //------------------------------------------------------------------------------
    #include "Forme.h"
    //==============================================================================
    template<typename T = int>//template par défaut = int
    class Cercle : public Forme
    {
    //------------------------------------------------------------------------------
    public:
        Cercle(const std::string& p_nom, const T p_rayon)
        : Forme(p_nom), m_rayon(p_rayon) {}
     
        T getRayon() const { return m_rayon; }
    //------------------------------------------------------------------------------
    private:
        T m_rayon;
    };
    //==============================================================================
    #endif
    Specialiser le template dans le .cpp
    .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
     
    #ifndef DEF_CERCLE
    #define DEF_CERCLE
    //==============================================================================
    #include <string>
    //------------------------------------------------------------------------------
    #include "Forme.h"
    //==============================================================================
    template<typename T = int>//template par défaut = int
    class Cercle : public Forme
    {
    //------------------------------------------------------------------------------
    public:
        Cercle(const std::string& p_nom, const T p_rayon);
        T getRayon() const;
    //------------------------------------------------------------------------------
    private:
        T m_rayon;
    };
    //==============================================================================
    #endif
    .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
    #include <iostream>
    #include <string>
    //------------------------------------------------------------------------------
    #include "Cercle.h"
    //------------------------------------------------------------------------------
    using namespace std;
    //==============================================================================
    template<>
    Cercle<int>::Cercle(const std::string& p_nom, const int p_rayon)
    : Forme(p_nom), m_rayon(p_rayon) {}
    //------------------------------------------------------------------------------
    template<>
    int Cercle<int>::getRayon() const 
    {
        return rayon;
    }
    //==============================================================================
    Les fonctions de classes template définies dans le .cpp doivent toutes être prefixées de template<> et de plus elles devront connaitre le type.
    (Pas forcement utile dans ce cas, cela obligerait à redefinir le constructeur et la fonction pour chaque type différents.)

    PS penser à mettre les arguements qui ne sont pas modifible en const, et utiliser les références si ceux-ci sont ne sont pas de simple valeurs (int, char ...)
    Les fonctions qui ne modifient rien seront constantes.
    Ne jamais utiliser de "using namespace std;" dans un header (.h)

  4. #4
    Expert éminent

    Femme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Juin 2007
    Messages
    5 202
    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 202
    Par défaut
    Par ailleurs, il y a une erreur sur qui est template.

    la classe déclaration est:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    template <typename T> class Cercle {
    public:
        Cercle(T p_rayon,string p_nom);
    };
    Ta définition était celle de template <typename T> Cercle::Cercle(T p_rayon,string p_nom).
    Ce n'est pas la même chose.
    Cette définition s'occupe de la template pour tout type T de la fonction (en l'occurence un constructeur) Cercle(T, string) de la classe Cercle.
    Sauf que tu veux la fonction Cercle(T, string) de la template pour tout type T de la classe Cercle.
    C'est à dire template <typename T> Cercle<T>::Cercle(T p_rayon,string p_nom).

    Ceci n'enlève rien aux explications précédentes

  5. #5
    Membre confirmé
    Homme Profil pro
    Étudiant
    Inscrit en
    Juillet 2013
    Messages
    70
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Juillet 2013
    Messages : 70
    Par défaut
    y'a une partie que je ne comprends pas, en mettant des <int> dans le .cpp (dans le code en bas)
    on perd le template. C'est à dire que si je fais

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
        Cercle<int> monCercle("Mon 1er Cercle",14);
    ça marche, mais si je fais

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
        Cercle<long> monCercle("Mon 1er Cercle",14);
    ça ne marche plus

    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
     
     
    #include <iostream>
    #include <string>
    //------------------------------------------------------------------------------
    #include "Cercle.h"
    //------------------------------------------------------------------------------
    using namespace std;
    //==============================================================================
    template<>
    Cercle<int>::Cercle(const std::string& p_nom, const int p_rayon)
    : Forme(p_nom), m_rayon(p_rayon) {}
    //------------------------------------------------------------------------------
    template<>
    int Cercle<int>::getRayon() const
    {
        return m_rayon;
    }
    //==============================================================================

  6. #6
    Membre émérite

    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
    Billets dans le blog
    1
    Par défaut
    Les fonctions de classes template définies dans le .cpp doivent toutes être prefixées de template<> et de plus elles devront connaitre le type.
    (Pas forcement utile dans ce cas, cela obligerait à redefinir le constructeur et la fonction pour chaque type différents.)
    Bon, je suis pas des gars les plus clair

    Les templates définies dans le fichier source devront être spécialisées, c'est à dire qu'elle devront explicitement definir le type.(cette spécialisation peut aussi être faite dans le header).

    C'est pour cela que dans de cas précis, il n'y a pas (a priori) d'interêt à utiliser de fichier source (.cpp), le seul header (.h) suffira à déclarer cette classe, pour garder en généricité.

    Un petit exemple pour mieux comprendre l'interêt de la spécialisation : (pas vraiment d'intérêt mais c'est pour donner une idée)
    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
    //==============================================================================
    #include <iostream>
    //------------------------------------------------------------------------------
    struct CircleTag {};
    struct SquareTag {};
    //------------------------------------------------------------------------------
    template<typename FormTag>
    struct Form
    {
        void print() const;
    };
    //------------------------------------------------------------------------------
    template<>//Ainsi spécialisé, peut être mis dans un .cpp
    void Form<CircleTag>::print() const
    {
        std::cout << "Cercle" << std::endl;
    }
    //------------------------------------------------------------------------------
    template<>
    void Form<SquareTag>::print() const
    {
        std::cout << "Carre" << std::endl;
    }
    //==============================================================================
    int main()
    {
        Form<CircleTag> cercle;
        Form<SquareTag> carre;
     
        cercle.print();//Affiche Cercle
        carre.print();//Affiche Carre
        return 0;
    }
    //==============================================================================

  7. #7
    Membre confirmé
    Homme Profil pro
    Étudiant
    Inscrit en
    Juillet 2013
    Messages
    70
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Juillet 2013
    Messages : 70
    Par défaut
    ok merci, j'ai compris

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

Discussions similaires

  1. Réponses: 2
    Dernier message: 01/12/2011, 13h16
  2. Problème d'écriture dans un fichier de log
    Par yakotey dans le forum Administration système
    Réponses: 14
    Dernier message: 22/11/2005, 15h08
  3. [C#] Probleme d'écriture dans un fichier XML
    Par Joad dans le forum ASP.NET
    Réponses: 5
    Dernier message: 02/05/2005, 16h19
  4. probleme d'ecriture dans un fichier texte
    Par azrael88370 dans le forum VB 6 et antérieur
    Réponses: 3
    Dernier message: 24/01/2005, 17h33
  5. Probleme d'ecriture dans un fichier en mode Text
    Par bbozet dans le forum C++Builder
    Réponses: 3
    Dernier message: 14/01/2004, 13h46

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