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 :

Spécialisation partielle et typedef de template.


Sujet :

Langage C++

  1. #1
    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
    Points : 13 017
    Points
    13 017
    Par défaut Spécialisation partielle et typedef de template.
    Bonjour,
    J'ai une classe template quelconque :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    template<class T>struct ok {};
    Je déclare une classe trait :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    template<class T> struct trait;
    et je la spécialise pour ma première classe template :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    template<class T> struct trait<ok<T> >
    {
       static const std::string tell_me;
    };
    template<class T>
    const std::string trait<ok<T> >::tell_me="ok<T>";
    Ca marche :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    #include <iostream>
    int main()
    {
       std::cout<<trait<ok<double> >::tell_me <<std::endl;
       return 0;
    }
    Jusque là tout va bien.
    Mais en attendant les alias de template, je fais ça :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    template<class T> struct problem
    {};
    template<class T> struct rebind
    {
       typedef problem<T> type;
    };
    Et lorsque j'essaie de spécialiser partiellement ma classe trait :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    template<class T> struct trait<typename rebind<T>::type >
    {
       static const std::string tell_me;
    };
    template<class T>
    const std::string trait<typename rebind<T>::type >::tell_me="problem<T>";
    Je me fais jeter
    Citation Envoyé par VCExpress
    error C2764: 'T'*: paramètre de modèle non utilisé ou pouvant être déduit dans la spécialisation partielle 'trait<rebind<T>::type>'
    Citation Envoyé par MinGW
    error: template parameters not used in partial specialization
    Je comprend pas pourquoi le code est incorrect. Mais surtout, je vois pas comment contourner sauf à faire :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    template<class T> struct trait<problem<T> >/*<typename rebind<T>::type >*/
    {
       static const std::string tell_me;
    };
    template<class T>
    const std::string trait<problem<T> >::tell_me="rebind<T>";
    car bien sur dans la vraie vie problem<T> est un peu plus compliqué que ça.

    Avez-vous des idées/solutions ?

  2. #2
    Membre chevronné
    Avatar de Goten
    Profil pro
    Inscrit en
    Juillet 2008
    Messages
    1 580
    Détails du profil
    Informations personnelles :
    Âge : 33
    Localisation : France

    Informations forums :
    Inscription : Juillet 2008
    Messages : 1 580
    Points : 2 205
    Points
    2 205
    Par défaut
    Hum chez moi le code que tu fournies compile, et à première vue je vois pas de raisons qui ferait que ça compile pas.
    "Hardcoded types are to generic code what magic constants are to regular code." --A. Alexandrescu

  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
    Points : 13 017
    Points
    13 017
    Par défaut
    Citation Envoyé par Goten Voir le message
    Hum chez moi le code que tu fournies compile, et à première vue je vois pas de raisons qui ferait que ça compile pas.
    Ca :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    template<class T> struct trait<typename rebind<T>::type >
    {
       static const std::string tell_me;
    };
    Ne compile pas chez moi
    Voici un source complet :
    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
    #include <string>
     
    template<class T>
    struct dummy
    {
    };
     
    template<class T> struct trait;
    template<class T> struct trait<dummy<T> >
    {
       static const std::string tell_me;
    };
    template<class T>
    const std::string trait<dummy<T> >::tell_me="dummy<T>";
     
    template<class T> struct problem
    {};
    template<class T> struct rebind
    {
       typedef problem<T> type;
    };
     
    template<class T> struct trait<typename rebind<T>::type >
    {
       static const std::string tell_me;
    };
    template<class T>
    const std::string trait<problem<T> >::tell_me="rebind<T>";
     
    #include <iostream>
    int main()
    {
       std::cout<<trait<dummy<double> >::tell_me <<std::endl;
       std::cout<<trait<rebind<double>::type >::tell_me <<std::endl;
       return 0;
    }

  4. #4
    Membre chevronné
    Avatar de Goten
    Profil pro
    Inscrit en
    Juillet 2008
    Messages
    1 580
    Détails du profil
    Informations personnelles :
    Âge : 33
    Localisation : France

    Informations forums :
    Inscription : Juillet 2008
    Messages : 1 580
    Points : 2 205
    Points
    2 205
    Par défaut
    En effet là ça compile pas. Autant pour moi juste le bout de code compilé, mais me manquer un copié .

    edit : fiou... les copié collé aujourd'hui -_-
    "Hardcoded types are to generic code what magic constants are to regular code." --A. Alexandrescu

  5. #5
    Expert éminent

    Inscrit en
    Novembre 2005
    Messages
    5 145
    Détails du profil
    Informations forums :
    Inscription : Novembre 2005
    Messages : 5 145
    Points : 6 911
    Points
    6 911
    Par défaut
    A partir d'un type foo, tu ne peux jamais deduire quel est le type T qui correspond a typename rebind<T>::type, donc la specialisation partielle est inutilisable. Tout comme avec
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    template <class T> int bar(typename rebind<T>::type);
    tu ne peux pas t'attendre a ce que le compilateur deduise de bar(exp) quel valeur de T il doit utiliser.

    Les messages d'erreur ne sont pas geniaux. Celui de VC me semble meme mal redige (pb de traduction?). Si j'aurais bien vu une negation: "... ne pouvant être déduit"
    Les MP ne sont pas là pour les questions techniques, les forums sont là pour ça.

  6. #6
    Membre confirmé
    Inscrit en
    Août 2004
    Messages
    556
    Détails du profil
    Informations forums :
    Inscription : Août 2004
    Messages : 556
    Points : 588
    Points
    588
    Par défaut
    Tu as donné la réponse toi même, ce n'est pas valide.
    Ca fonctionnait avec GCC 4.1.2, depuis plus, et c'est voulu.

    Le compilateur ne peut déduire T à partir de rebind< T >::type.

    http://gcc.gnu.org/ml/gcc-patches/2008-01/msg00482.html

    (erf trop lent)

  7. #7
    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
    Points : 13 017
    Points
    13 017
    Par défaut
    Citation Envoyé par Jean-Marc.Bourguet Voir le message
    A partir d'un type foo, tu ne peux jamais deduire quel est le type T qui correspond a typename rebind<T>::type, donc la specialisation partielle est inutilisable.
    J'ai l'impression de comprendre mais comme j'arrive pas à le formuler en terme clair, ça me dérange.

    J'ai le sentiment que je raisonnais à l'envers. Je partais de mes définitions et aboutissait à une expression. En fait le compilo fonctionne à l'envers : à partir de l'expression il détermine quelle spécialisation s'applique et il ne peut utiliser celle-ci.

  8. #8
    Expert éminent

    Inscrit en
    Novembre 2005
    Messages
    5 145
    Détails du profil
    Informations forums :
    Inscription : Novembre 2005
    Messages : 5 145
    Points : 6 911
    Points
    6 911
    Par défaut
    Citation Envoyé par 3DArchi Voir le message
    J'ai l'impression de comprendre mais comme j'arrive pas à le formuler en terme clair, ça me dérange.

    J'ai le sentiment que je raisonnais à l'envers. Je partais de mes définitions et aboutissait à une expression. En fait le compilo fonctionne à l'envers : à partir de l'expression il détermine quelle spécialisation s'applique et il ne peut utiliser celle-ci.
    Comment veux-tu qu'il fasse autrement? Tu utilises traits<foo> (que tu ait optenu foo a partir d'un typedef dans un template ou autrement n'a pas d'importance, tu ne voudrais quand meme pas que ca intervienne, non?) et pour que la specialisation partielle soit utilisable, il faut pouvoir en deduire les parametres avec lesquelles la specialisation est instanciee.
    Les MP ne sont pas là pour les questions techniques, les forums sont là pour ça.

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

Discussions similaires

  1. Spécialisation partielle d'une fonction template
    Par N0vember dans le forum Langage
    Réponses: 4
    Dernier message: 17/10/2010, 20h49
  2. [Template] Spécialisation partielle d'un template
    Par Kurisu dans le forum Langage
    Réponses: 31
    Dernier message: 25/11/2008, 22h21
  3. [Template] spécialisation partielle des template
    Par vikki dans le forum Langage
    Réponses: 9
    Dernier message: 10/11/2008, 16h29
  4. Réponses: 4
    Dernier message: 15/10/2008, 09h33
  5. Réponses: 4
    Dernier message: 04/09/2008, 10h58

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