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
    Nouveau membre du Club
    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
    Points : 38
    Points
    38
    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 115
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 36
    Localisation : Canada

    Informations professionnelles :
    Activité : Network game programmer

    Informations forums :
    Inscription : Juin 2010
    Messages : 7 115
    Points : 32 967
    Points
    32 967
    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 éclairé

    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
    Points : 877
    Points
    877
    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 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
    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
    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

  5. #5
    Nouveau membre du Club
    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
    Points : 38
    Points
    38
    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 éclairé

    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
    Points : 877
    Points
    877
    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
    Nouveau membre du Club
    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
    Points : 38
    Points
    38
    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