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 :

Templates et specialisation


Sujet :

C++

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre averti
    Profil pro
    Inscrit en
    Août 2010
    Messages
    12
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Août 2010
    Messages : 12
    Par défaut Templates et specialisation
    Bonjour,

    J'ai le code suivant :

    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
    template<typename T>
    T FromString(const std::string & Str, bool & Res)
    {
       T Dest = T();
       std::istringstream iss( Str );
       Res = iss >> Dest != 0;
       return Dest;
    }
     
    template<>
    bool FromString<bool>(const std::string & Str, bool & Res) 
    {
    	bool Dest = false;
    // Trucs differents
    	return Dest;
    }
    Pb, vraisemblablement à cause de la signature, j'obtiens des pbs au link (code déjà défini).
    Comment faire dans une situation pareille lorsque le type de template n'apparait pas en passage de paramètres ?

    Je veux pouvoir faire des
    int toto = FromString<int>(...);
    bool toto = FromString<bool>(...);
    La bonne fonction étant automatiquement appelée...

    Merci pour vos remarques

  2. #2
    Membre Expert

    Homme Profil pro
    Développeur informatique
    Inscrit en
    Septembre 2007
    Messages
    1 895
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 49
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Opérateur de télécommunications

    Informations forums :
    Inscription : Septembre 2007
    Messages : 1 895
    Par défaut
    Il faut rajouter le mot clef inline si je ne m'abuse.
    [FAQ des forums][FAQ Développement 2D, 3D et Jeux][Si vous ne savez pas ou vous en êtes...]
    Essayez d'écrire clairement (c'est à dire avec des mots français complets). SMS est votre ennemi.
    Evitez les arguments inutiles - DirectMachin vs. OpenTruc ou G++ vs. Café. C'est dépassé tout ça.
    Et si vous êtes sages, vous aurez peut être vous aussi la chance de passer à la télé. Ou pas.

    Ce site contient un forum d'entraide gratuit. Il ne s'use que si l'on ne s'en sert pas.

  3. #3
    Rédacteur
    Avatar de 3DArchi
    Profil pro
    Inscrit en
    Juin 2008
    Messages
    7 634
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2008
    Messages : 7 634
    Par défaut
    Citation Envoyé par Emmanuel Deloget Voir le message
    Il faut rajouter le mot clef inline si je ne m'abuse.
    Tu ne t'abuses pas.
    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
    template<typename T>
    inline T FromString(const std::string & Str, bool & Res)
    {
       T Dest = T();
       std::istringstream iss( Str );
       Res = iss >> Dest != 0;
       return Dest;
    }
     
    template<>
    inline bool FromString<bool>(const std::string & Str, bool & Res) 
    {
    	bool Dest = false;
    // Trucs differents
    	return Dest;
    }

  4. #4
    screetch
    Invité(e)
    Par défaut
    hmmm j'aurait dit static au lieu de inline
    disons pour être pedantic (comme GCC) que l'effet recherché s'obtient avec static, et que inline marche aussi, avec l'effet supplémentaire d'inliner la fonction

    or l'effet demandé a l'origine c'est "static" non?

    de toutes facons j'aurais mis static inline si le code est assuez court =)

  5. #5
    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,
    Citation Envoyé par screetch Voir le message
    hmmm j'aurait dit static au lieu de inline
    disons pour être pedantic (comme GCC) que l'effet recherché s'obtient avec static, et que inline marche aussi, avec l'effet supplémentaire d'inliner la fonction

    or l'effet demandé a l'origine c'est "static" non?

    de toutes facons j'aurais mis static inline si le code est assuez court =)
    Non... l'effet demandé est bel et bien celui de inline!

    Le mot clé static ne déroge pas au respect de l'ODR (One Definition Rule), et son effet dépend des circonstances.

    Dans le plus complexe des cas, tu l'utilise sur une fonction membre d'une classe template sous la forme de
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    template <typename T>
    class MyClass
    {
        public:
             static void foo(MyClass const &)
             {
                  /*...*/
             }
    };
    qui va te permettre d'utiliser la fonction sans avoir besoin d'en créer une instance (c'est le but de static ) mais qui, surtout, sera implicitement déclarée inline parce que définie au sein meme de la définition de la classe en question!

    Si tu voulais d'ailleurs sortir la définition de la fonction de la classe, tu devrais avoir un code proche de
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    template <typename T>
    class MyClass
    {
        public:
             static void foo(MyClass const &);
    };
     
    inline void MyClass::foo(MyClass const &)
    {
        /*...*/
    }
    C'est en effet le seul moyen pour que l'éditeur de liens ne s'étonne pas de trouver plusieurs implémentations de fonctions représentées par le même symbole, car, en dehors de toute instanciation explicite, il ne faut pas oublier que le compilateur ne pourra créer le code binaire correspondant à la fonction que... lorsqu'il saura par quel type effectif remplacer T !!!

    Il est donc tout à fait possible que tu te retrouve, le compilateur travaillant comme il le fait, dans une situation où tu auras une implementation de MyClass<int>::foo dans XXX.cpp et une autre dans YYY.cpp, simplement pare que le compilateur "oublie" ce qu'il a pu faire entre XXX.cpp et YYY.cpp, à charge pour l'éditeur de liens de "remettre de l'ordre".

    Il n'est pas exclus, si la fonction n'est pas effectivement inlinée, que l'éditeur de liens ne corrige les symboles appelés et ne fasse en sorte qu'il n'y ait pour finir qu'un code binaire de la fonction correspondante, mais seul le mot clé pourra le prévenir qu'il doit agir de la sorte
    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

  6. #6
    Membre habitué
    Profil pro
    Inscrit en
    Novembre 2010
    Messages
    13
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Novembre 2010
    Messages : 13
    Par défaut
    Citation Envoyé par robosara Voir le message
    Bonjour,



    Pb, vraisemblablement à cause de la signature, j'obtiens des pbs au link (code déjà défini).
    Comment faire dans une situation pareille lorsque le type de template n'apparait pas en passage de paramètres ?

    Je veux pouvoir faire des
    int toto = FromString<int>(...);
    bool toto = FromString<bool>(...);
    La bonne fonction étant automatiquement appelée...

    Merci pour vos remarques
    J'ai l'impression, que tu dois inclure ta spécialisation ( et sa définition...) dans de multiples fichiers sources, et elle doit se retrouver dans de multiples fichiers objets.

    Parce que ton code compile sans problème de link.

    Essaies en déclarant uniquement ( ta spécialisation) dans ton fichier header, et la définissant dans un fichier source unique.

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

    Informations forums :
    Inscription : Août 2010
    Messages : 12
    Par défaut
    Merci à tous pour vos réponses.

    Ca fonctionne bien en mettant le "inline" au bon endroit

  8. #8
    screetch
    Invité(e)
    Par défaut
    je suis pas d'accord avec toi pour le coup;
    on parlait de fonctions libres, pas de fonctions de classe, donc je parlais de la version "C" de static.

  9. #9
    gl
    gl est déconnecté
    Rédacteur

    Homme Profil pro
    Inscrit en
    Juin 2002
    Messages
    2 165
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 46
    Localisation : France, Isère (Rhône Alpes)

    Informations forums :
    Inscription : Juin 2002
    Messages : 2 165
    Par défaut
    Citation Envoyé par screetch Voir le message
    je suis pas d'accord avec toi pour le coup;
    on parlait de fonctions libres, pas de fonctions de classe, donc je parlais de la version "C" de static.
    Avec inline, le compilateur accepte de voir plusieurs définition identique de la fonction mais celle ci n'est réellement présente qu'une seule fois dans l’exécutable (voir aucun si c'est inliné à chaque fois).

    Avec static, la fonction n'est visible que de l'unité de compilation courante, elle peut donc être visible plusieurs fois par le compilateur sans souci. Par contre il existera potentiellement plusieurs exemplaire du code de cette fonction dans l'exécutable final.

    Dans les deux cas, sauf réglage particulier du compilateur, la fonction sera inlinée ou non en fonction des critères de décision du compilateur (il n'a pas l'obligation d'inlinée une fonction inline ni l'interdiction de le faire sur d'autres fonctions).
    En C++ on utilise un namespace anonyme plutôt que static.

  10. #10
    screetch
    Invité(e)
    Par défaut
    je veux bien un lien ou une preuve =)

  11. #11
    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
    Citation Envoyé par screetch Voir le message
    je veux bien un lien ou une preuve =)
    lix.polytechnique.fr :
    static functions are functions that are only visable to other functions in the same file.
    Le problème avec les fonctions template, c'est que le compilateur a impérativement besoin du code C++ pour générer le code binaire correspondant car chaque fois qu'il va utiliser T, il devra prévoir plus ou moins de place si T est un char, un int ou n'importe quel type personnel

    Du coups, la définition de la fonction se trouvant dans le fichier d'en-tête, la dite fonction serait visible partout où le fichier est inclus, de manière directe ou indirecte...

    Le bénéfice du mot clé static (dans son acception C du terme) est donc nul, ou peut s'en faut

    En outre, il faut vraiment que ni le compilateur ni l'éditeur de liens ne s'étonne de trouver potentiellement plusieurs (ou aucune) fois la définition de la fonction
    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

Discussions similaires

  1. Class template et specialisation d'operateur
    Par alex.buisson dans le forum Langage
    Réponses: 2
    Dernier message: 22/04/2013, 16h10
  2. specialisation de template
    Par camboui dans le forum Langage
    Réponses: 2
    Dernier message: 29/01/2009, 14h16
  3. [Template] specialisation de classe template
    Par vandamme dans le forum Langage
    Réponses: 3
    Dernier message: 19/10/2008, 14h22
  4. specialisation de fonction template
    Par chubinou dans le forum Langage
    Réponses: 8
    Dernier message: 13/11/2007, 14h03
  5. Réponses: 5
    Dernier message: 29/12/2005, 21h27

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