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 :

Spécialisation de template et g++


Sujet :

C++

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre confirmé
    Homme Profil pro
    Développeur de jeux vidéo
    Inscrit en
    Août 2011
    Messages
    88
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Développeur de jeux vidéo

    Informations forums :
    Inscription : Août 2011
    Messages : 88
    Par défaut Spécialisation de template et g++
    Bonjour,

    Voici un code tout simple que je veux faire compiler avec g++ sous C::B :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    class X
    {
    	public:
     
    		template <class T> T get_property ()
    		{
    		}
     
    		template <> string get_property ()
    		{
    		}
    };
    J'ai malheureusement l'erreur suivante :

    error: explicit specialization in non-namespace scope 'class config'
    Je veux pouvoir faire x->get_property () mais apparemment je n'ai pas le droit de spécialiser hors d'un namespace, ce qui ne me convient pas puisque je veux que la spécialisation soit une fonction membre de ma classe ... Que faire ?

  2. #2
    Inactif  


    Homme Profil pro
    Inscrit en
    Novembre 2008
    Messages
    5 288
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 49
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Secteur : Santé

    Informations forums :
    Inscription : Novembre 2008
    Messages : 5 288
    Par défaut
    Bonjour

    La FAQ correspondante : Qu'est-ce que la spécialisation de template ?

    La spécialisation d'une fonction template d'une classe est identique à la spécialisation d'une fonction :
    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
    class X
    {
    public:
     
        template <class T> T get_property()
        {
            return T();
        }
    };
     
    template<>
    std::string X::get_property<std::string>()
    {
        return std::string();
    }
     
    X x;
    x.get_property<int>();
    x.get_property<std::string>();
    PS : en fait, il est même préférable de bien séparé déclaration et définition donc sort de la classe la définition de ta fonction template :

    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
    class X
    {
    public:
        template<typename T> T get_property();
    };
     
    template<typename T>
    T X::get_property()
    {
        return T();
    }
     
    template<>
    std::string X::get_property<std::string>()
    {
        return std::string();
    }
    PS2 : utilise typename au lieu de class dans les paramètres template
    PS3 : je sais pas si c'est le cas mais ne fait pas de using namespace std; dans un fichier d'en-tête

  3. #3
    Membre confirmé
    Homme Profil pro
    Développeur de jeux vidéo
    Inscrit en
    Août 2011
    Messages
    88
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Développeur de jeux vidéo

    Informations forums :
    Inscription : Août 2011
    Messages : 88
    Par défaut
    Merci, j'avais beau avoir jeté un oeil à la FAQ, j'ai dû avoir zappé ce passage ...

    J'ai néanmoins une question : si je sépare l'implémentation de la fonction de sa définition, je dois bien le faire dans le fichier .hpp pour les templates, et pas dans le .cpp ? (juste pour la confirmation).

    Et non, je n'ai aucun #include ni aucun using namespace dans mes fichiers de header.

    PS : Comment écrire un bout de ligne de code en ligne comme tu l'as fait ?

  4. #4
    Inactif  


    Homme Profil pro
    Inscrit en
    Novembre 2008
    Messages
    5 288
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 49
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Secteur : Santé

    Informations forums :
    Inscription : Novembre 2008
    Messages : 5 288
    Par défaut
    Citation Envoyé par Nekkro Voir le message
    J'ai néanmoins une question : si je sépare l'implémentation de la fonction de sa définition, je dois bien le faire dans le fichier .hpp pour les templates, et pas dans le .cpp ? (juste pour la confirmation).
    Oui. Par contre, il arrive parfois que l'on déplace l'implémentation dans un autre fichier header pour des raisons de lisibilité (par exemple, dans un fichier xxx_impl.hpp)

    Citation Envoyé par Nekkro Voir le message
    PS : Comment écrire un bout de ligne de code en ligne comme tu l'as fait ?
    avec la balise CODEINLINE

  5. #5
    Membre confirmé
    Homme Profil pro
    Développeur de jeux vidéo
    Inscrit en
    Août 2011
    Messages
    88
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Développeur de jeux vidéo

    Informations forums :
    Inscription : Août 2011
    Messages : 88
    Par défaut
    Je te remercie, mon problème est résolu.

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

    Informations professionnelles :
    Activité : aucun

    Informations forums :
    Inscription : Octobre 2004
    Messages : 11 644
    Par défaut
    Salut,

    Il y a cependant un dernier point sur lequel il faut attirer l'attention, c'est le fait que toutes les définitions de fonctions template (ou de fonction membres de classes template) doivent être déclarées inline, soit de manière implicite, parce que définies à l'intérieur de la définition de la classe
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    template <typename T>
    class MyClass
    {
        public:
            /* cette fonction sera automatiquement et implicitement considérée
             * inline
             */
            void foo(T const & truc)
            {
                /* fais quelque chose */
            }
    };
    soit de manière explicite, lors de la définition
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    template <>
    class MyClass<std::string>
    {
        public:
            void foo(std::string const & truc);
    };
    template <>
    inline MyClass<std::string>::foo(std::string const & truc)
    {
        /* spécialisation pour l'utilisation de std::string */
    }
    Autrement, comme le compilateur va créer le code binaire correspondant dans tous les fichiers d'implémentation dans lequel le fichier d'en-tête sera inclus (de manière directe ou indirecte), l'éditeur de lien ralera de trouver plusieurs fois le même symbole pour cette fonction et ne saura pas vers quelle adresse mémoire faire pointer l'appel de la fonction.

    Le fait d'avoir indiqué (de manière implicite ou explicite) que la fonction est inline permet à l'éditeur de liens de savoir comment réagir face à cette présence mutliple du même symbole (sans doute en ne gardant qu'une implémentation, si la fonction n'est pas effectivement inlinée )
    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

  7. #7
    Membre confirmé
    Homme Profil pro
    Développeur de jeux vidéo
    Inscrit en
    Août 2011
    Messages
    88
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Développeur de jeux vidéo

    Informations forums :
    Inscription : Août 2011
    Messages : 88
    Par défaut
    J'ai modifié et voilà ce que ça donne :

    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
    class Config
    {
    	public:
    		template <typename T> T get_property (const string & name, const T & default_value);
    /* ... */
    };
     
    template <typename T> inline T Config::get_property (const string & name, const T & default_value)
    {
    }
     
    template <> inline const string & Config::get_property<string> (const string & name, const string & default_value)
    {
    }
     
    template <> inline bool Config::get_property<bool> (const string & name, bool default_value)
    {
    }
    Et j'ai les erreurs suivantes :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    error: template-id 'get_property<std::string>' for 'const std::string& Config::get_property(const std::string&, const std::string&)' does not match any template declaration
    error: template-id 'get_property<bool>' for 'bool Config::get_property(const std::string&, bool)' does not match any template declaration
    Je vous avoue ne pas bien comprendre l'erreur ...

  8. #8
    Membre Expert
    Homme Profil pro
    Chercheur
    Inscrit en
    Mars 2010
    Messages
    1 218
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Chercheur

    Informations forums :
    Inscription : Mars 2010
    Messages : 1 218
    Par défaut
    Bonjour koala,

    Citation Envoyé par koala01 Voir le message
    Autrement, comme le compilateur va créer le code binaire correspondant dans tous les fichiers d'implémentation dans lequel le fichier d'en-tête sera inclus (de manière directe ou indirecte), l'éditeur de lien ralera de trouver plusieurs fois le même symbole pour cette fonction et ne saura pas vers quelle adresse mémoire faire pointer l'appel de la fonction.
    tu ne peux pas provoquer le problème de définition multiple que tu mentionnes?

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

Discussions similaires

  1. Spécialisation de template particulière
    Par Flo. dans le forum Langage
    Réponses: 4
    Dernier message: 25/03/2009, 22h18
  2. Spécialisation de template parametre avec Enum
    Par 3DArchi dans le forum Langage
    Réponses: 4
    Dernier message: 24/09/2008, 15h21
  3. Spécialisation de template
    Par bobyjoe dans le forum Langage
    Réponses: 18
    Dernier message: 13/12/2007, 21h52
  4. Réponses: 8
    Dernier message: 24/04/2007, 22h09
  5. Réponses: 7
    Dernier message: 01/01/2006, 03h28

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