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

Langage C++ Discussion :

Template interdite.


Sujet :

Langage C++

  1. #1
    Membre du Club
    Inscrit en
    Septembre 2003
    Messages
    49
    Détails du profil
    Informations forums :
    Inscription : Septembre 2003
    Messages : 49
    Points : 43
    Points
    43
    Par défaut Template interdite.
    Bonjour a tous.
    Voila comme je ne suis pas tres "templatiste" j'aurai besoin de vote aide pour resoudre un petit pb:

    Soit la class suivante:

    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
    template<typename T,int Base>
    class IntegerTrait
    {
       public:
          const bool IsSigned;
          const T Max;
          const T Min;
     
          .../...
     
          IntegerTrait(T);
     
          std::string ToString() const;
     
     
          ../..      
    };
    Il s'agit d'une classe qui regroupe les caracteristiques des entiers en fonction de une base "Base"

    J'aimerai trouve un moyen pour interdire l'utilisation de cette classe pour certaines valeur de Base notamment 0 et 1.
    merci

  2. #2
    Rédacteur
    Avatar de Laurent Gomila
    Profil pro
    Développeur informatique
    Inscrit en
    Avril 2003
    Messages
    10 651
    Détails du profil
    Informations personnelles :
    Âge : 39
    Localisation : France, Moselle (Lorraine)

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Avril 2003
    Messages : 10 651
    Points : 15 920
    Points
    15 920
    Par défaut
    Tu peux par exemple spécialiser partiellement ta classe pour ces valeurs, et faire en sorte que ces spécialisations génèrent une erreur de compilation si on tente de les utiliser. Par exemple tu peux ne rien mettre dedans, ou déclarer le constructeur privé, etc...

    Après tu peux aussi imaginer des choses un peu plus poussées, afin d'afficher un message d'erreur qui soit plus explicite pour l'utilisateur.

  3. #3
    Membre du Club
    Inscrit en
    Septembre 2003
    Messages
    49
    Détails du profil
    Informations forums :
    Inscription : Septembre 2003
    Messages : 49
    Points : 43
    Points
    43
    Par défaut
    Simple et elegant!!!
    Tres bonne idee merci.

  4. #4
    Membre du Club
    Inscrit en
    Septembre 2003
    Messages
    49
    Détails du profil
    Informations forums :
    Inscription : Septembre 2003
    Messages : 49
    Points : 43
    Points
    43
    Par défaut
    Salut
    J'ai un autre pb.En compilant (sur VC7):

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    //specialization for <int,Base>
     
    template<int Base>
    const bool TyIntegerTrait<int,Base>::IsSigned = true;
    //----------------------------------------------------------------------
     
    //specialization for <unsigned,Base>
     
    template<int Radix>
    const bool TyIntegerTrait<unsigned,Base>::IsSigned = false;
    //--------------------------------------------------------------------------
    j'obtient une erreur de compilation:

    d:\Mes Documents\My Projects\Include\BKacl\IntegerTrait.h(97): error C2086: 'const bool bklib::TyIntegerTrait<Ty,>::IsSigned' : redefinition
    J'obtient ce meme message por l'ensemble des specialisations (short unsigned short,char ...)

    Heeeeeeeeelp

  5. #5
    Rédacteur
    Avatar de Laurent Gomila
    Profil pro
    Développeur informatique
    Inscrit en
    Avril 2003
    Messages
    10 651
    Détails du profil
    Informations personnelles :
    Âge : 39
    Localisation : France, Moselle (Lorraine)

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Avril 2003
    Messages : 10 651
    Points : 15 920
    Points
    15 920
    Par défaut
    Une spécialisation doit redéfinir entièrement la classe, pas seulement ce qui t'arrange

  6. #6
    Membre du Club
    Inscrit en
    Septembre 2003
    Messages
    49
    Détails du profil
    Informations forums :
    Inscription : Septembre 2003
    Messages : 49
    Points : 43
    Points
    43
    Par défaut
    La je n'ai pas bien saisi.

    Redefinir toute la classe dans le sens:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    template<>
    class IntegerTrait<int,Base>
    {.../...};
    ou alors tous les parametres:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    template<>
    const bool IntegerTrait<int,10>::IsSigned = true;
     
    template<>
    const bool IntegerTrait<int,16>::IsSigned = true;
     
    .../..
    A savoir qu'une specialisation parielle de la cte IsSigned du genre

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    template<typename Base>
    const bool IntergerTrait<int,Base>::IsSigned = true;
    se compile correctement tant qu'aucune autre specialisation (autre que pour T = int) n'est definie.

  7. #7
    Rédacteur

    Avatar de Matthieu Brucher
    Profil pro
    Développeur HPC
    Inscrit en
    Juillet 2005
    Messages
    9 810
    Détails du profil
    Informations personnelles :
    Âge : 42
    Localisation : France, Pyrénées Atlantiques (Aquitaine)

    Informations professionnelles :
    Activité : Développeur HPC
    Secteur : Industrie

    Informations forums :
    Inscription : Juillet 2005
    Messages : 9 810
    Points : 20 970
    Points
    20 970
    Par défaut
    Si tu regardes bien ton code, tu a écrit deux fois la même chose avec juste isSigned qui change, donc ça ne va pas. Si tu veux spécialiser ton template, spécialise-le vraiment, ne change pas juste le nom - qui n'existera pas au moment de l'instantiation : si tu fais IntegerTraits<2>, il doit prendre quel template ??

  8. #8
    Rédacteur
    Avatar de Laurent Gomila
    Profil pro
    Développeur informatique
    Inscrit en
    Avril 2003
    Messages
    10 651
    Détails du profil
    Informations personnelles :
    Âge : 39
    Localisation : France, Moselle (Lorraine)

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Avril 2003
    Messages : 10 651
    Points : 15 920
    Points
    15 920
    Par défaut
    Redefinir toute la classe dans le sens:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    template<>
    class IntegerTrait<int,Base>
    {.../...};
    Oui.

  9. #9
    Rédacteur

    Avatar de Matthieu Brucher
    Profil pro
    Développeur HPC
    Inscrit en
    Juillet 2005
    Messages
    9 810
    Détails du profil
    Informations personnelles :
    Âge : 42
    Localisation : France, Pyrénées Atlantiques (Aquitaine)

    Informations professionnelles :
    Activité : Développeur HPC
    Secteur : Industrie

    Informations forums :
    Inscription : Juillet 2005
    Messages : 9 810
    Points : 20 970
    Points
    20 970
    Par défaut
    Bon, quant à moi, j'ai mal regardé le code
    En tout cas, dans la deuxième spécialisation, tu as un template int Radix qui n'est jamais utilisé, juste un Base qui lui n'est pas défini.

  10. #10
    Membre du Club
    Inscrit en
    Septembre 2003
    Messages
    49
    Détails du profil
    Informations forums :
    Inscription : Septembre 2003
    Messages : 49
    Points : 43
    Points
    43
    Par défaut
    Citation Envoyé par Miles
    Bon, quant à moi, j'ai mal regardé le code
    En tout cas, dans la deuxième spécialisation, tu as un template int Radix qui n'est jamais utilisé, juste un Base qui lui n'est pas défini.
    Desole c'une faute de frappe.

    Donc apparament pas moyen de specialiser unquement les ctes.bien.

    Soint

    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
    template<typename Ty,int Radix>
    class IntegerTrait
    {
       public:
          static const bool IsSigned;
          static const Ty Max;
          static const Ty Min;
          .../...
     
          const std::string ToString() const;
     
       protected:
       private:
          static const wchar_t char_set[Radix];
    };
     
     
    //Specialisation for Ty = int
     
    template<int radix>
    class IntegerTrait
    {
       public:
          static const bool IsSigned;
          static const int Max;
          static const int Min;
          .../...
     
          const std::string ToString() const;
     
       protected:
       private:
          static const wchar_t char_set[Radix];
    };
     
    template<int Radix>
    const bool
    IntegerTrait<Radix>::IsSigned = true;
     
    template<int Radix>
    const wchar_t
    IntegerTrait<Radix>::char_set[] = ?? //1
     
     
    .../...
     
    //----------
    //Specialisation for Radix= 4
     
    template<typename Ty>
    class IntegerTrait
    {
       public:
          static const bool IsSigned;
          static const int Max;
          static const int Min;
          .../...
     
          const std::string ToString() const;
     
       protected:
       private:
          static const wchar_t char_set[4];
    };
     
    template<typename Ty>
    const wchar_t
    IntegerTrait<Ty>::char_set[] = {0,1,2,3};
     
    template<typename Ty>
    const bool
    IntegerTrait<Ty>::IsSigned = ?? //2
    Comment initaliser 1 et 2?
    Ensuite si je fais IntegerTrait<int,4> le compileur se plains d'une ambiguite (entre les 2 specialisations). comment faire?
    Merci de votre patience

  11. #11
    Rédacteur

    Avatar de Matthieu Brucher
    Profil pro
    Développeur HPC
    Inscrit en
    Juillet 2005
    Messages
    9 810
    Détails du profil
    Informations personnelles :
    Âge : 42
    Localisation : France, Pyrénées Atlantiques (Aquitaine)

    Informations professionnelles :
    Activité : Développeur HPC
    Secteur : Industrie

    Informations forums :
    Inscription : Juillet 2005
    Messages : 9 810
    Points : 20 970
    Points
    20 970
    Par défaut
    Tu peux créer une autre classe qui contiendra tes constantes et tu ajoutes cette classe comme membre de ta classe parente ou tu en hérites.
    Ensuite, ton 1 et ton 2 sont à nouveau bizarre. Radix, OK, ce sera un entier. Ty, c'est quoi ?

  12. #12
    Rédacteur
    Avatar de Laurent Gomila
    Profil pro
    Développeur informatique
    Inscrit en
    Avril 2003
    Messages
    10 651
    Détails du profil
    Informations personnelles :
    Âge : 39
    Localisation : France, Moselle (Lorraine)

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Avril 2003
    Messages : 10 651
    Points : 15 920
    Points
    15 920
    Par défaut
    Ta syntaxe est encore incorrecte, là tu ne spécialises rien du tout.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    // Définition la plus générique
    template<typename Ty,int Radix>
    class IntegerTrait;
     
    // Specialisation for Ty = int
    template<int radix>
    class IntegerTrait<int, radix>;
     
    // Specialisation for Radix = 4
    template<typename Ty>
    class IntegerTrait<Ty, 4>;
    Du coup ça t'aidera sûrement à répondre à tes questions.

  13. #13
    Membre du Club
    Inscrit en
    Septembre 2003
    Messages
    49
    Détails du profil
    Informations forums :
    Inscription : Septembre 2003
    Messages : 49
    Points : 43
    Points
    43
    Par défaut
    Ok j'ai saisi le truc.

    Maintenat si je declare ma class IntegerTrait<Ty,Radix> et qlq specialisations de cette classe (ex IntegerTrait<int,10>,..).

    1-Suis - je oblige de definir tous les membres de ctte classe. (Disons je laisse certaines cte sans initialisation).

    2-Si je derive une autre classe :

    ex:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    class LongTrait: public IntegerTrait<long,10>
    {}
    et que je redefinisse un membre de ma classe base:
    ex:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    //dans IntegerTrait.h
     
    template<typename Ty,int Radix>
    const bool 
    IntgerTrait<Ty,Radix>::IsSigned = true; //IsSigned est static
     
    //dans LongTrait.cpp
    const bool LongTrait::IsSigned = false;
    Est ce que cette "redifinition" est consideree comme une specialisation ou s'agit d'une surcharge de variable.

    Merci

  14. #14
    Rédacteur

    Avatar de Matthieu Brucher
    Profil pro
    Développeur HPC
    Inscrit en
    Juillet 2005
    Messages
    9 810
    Détails du profil
    Informations personnelles :
    Âge : 42
    Localisation : France, Pyrénées Atlantiques (Aquitaine)

    Informations professionnelles :
    Activité : Développeur HPC
    Secteur : Industrie

    Informations forums :
    Inscription : Juillet 2005
    Messages : 9 810
    Points : 20 970
    Points
    20 970
    Par défaut
    Et là, attention, si tu veux de l'<int, 4>, il ne pourra pas décider lequel prendre dans ce cas

  15. #15
    Rédacteur
    Avatar de Laurent Gomila
    Profil pro
    Développeur informatique
    Inscrit en
    Avril 2003
    Messages
    10 651
    Détails du profil
    Informations personnelles :
    Âge : 39
    Localisation : France, Moselle (Lorraine)

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Avril 2003
    Messages : 10 651
    Points : 15 920
    Points
    15 920
    Par défaut
    1/ Si tu ne les redéfinis pas, elles n'existeront pas. Donc si tu n'en as pas besoin OK, sinon il faut le faire.

    2/ Redéfinir une variable membre statique d'une classe de base à partir d'une dérivée est interdit en C++. Donc tu ne pourras jamais définir un LongTrait::IsSigned.

    Et là, attention, si tu veux de l'<int, 4>, il ne pourra pas décider lequel prendre dans ce cas
    Oui, attention à ça aussi

    En fait j'ai l'impression que tu t'y prends mal. Est-ce que ce ne serait pas plus facile et correct de définir deux classes templates, une pour le type et une pour la base ? Parce que là, quel lien fais-tu entre les caractéristiques d'un type, et les choses relatives à la base ? Est-ce que tu ne fais pas un mix barbare qui n'a rien à faire là ?

Discussions similaires

  1. unsigned template interdit ?
    Par camboui dans le forum Langage
    Réponses: 7
    Dernier message: 05/01/2009, 11h54
  2. appliquer plusieurs templates
    Par Manu_Just dans le forum XSL/XSLT/XPATH
    Réponses: 7
    Dernier message: 04/04/2003, 16h26
  3. template match="node() mais pas text()"
    Par Manu_Just dans le forum XSL/XSLT/XPATH
    Réponses: 4
    Dernier message: 26/03/2003, 10h52
  4. [XSLT] template
    Par demo dans le forum XSL/XSLT/XPATH
    Réponses: 4
    Dernier message: 09/09/2002, 11h31

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