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 :

void, passé par template, comme type d'argument d'une fonction


Sujet :

C++

  1. #1
    Membre éprouvé Avatar de cs_ntd
    Homme Profil pro
    Développeur .NET
    Inscrit en
    Décembre 2006
    Messages
    598
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Etats-Unis

    Informations professionnelles :
    Activité : Développeur .NET
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Décembre 2006
    Messages : 598
    Points : 1 215
    Points
    1 215
    Par défaut void, passé par template, comme type d'argument d'une fonction
    Bonjour à tous,

    Je ne m'explique pas ce problème :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
     
    template<class T1, class T2>
    class C
    {
    public:
        typedef T1 (*Fptr)(void); //La ligne importante
        Fptr fptr;
    };
     
    int main()
    {
        C<void,void> c;
        return 0;
    }
    (Je sais que je n'utilise pas T2 pour l'instant).
    Ce code fonctionne parfaitement. En revanche:

    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
     
    template<class T1, class T2>
    class C
    {
    public:
        //T2 à la place de void pour le type de l'argument
        typedef T1 (*Fptr)(T2); //invalid parameter type `void'
        Fptr fptr; //invalid parameter type `void'
    };
     
    int main()
    {
        C<void,void> c;
        return 0;
    }
    Ce code ne fonctionne pas, j'ai mis les erreurs en face des lignes que le compilateur incrimine.

    C'est peut-être tout bête, mais j'aimerais savoir la subtilité qui empeche la 2ème version de fonctionner -_-'

    Merci d'avance de votre aide...

  2. #2
    Membre chevronné
    Avatar de Joel F
    Homme Profil pro
    Chercheur en informatique
    Inscrit en
    Septembre 2002
    Messages
    918
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 44
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Chercheur en informatique
    Secteur : Service public

    Informations forums :
    Inscription : Septembre 2002
    Messages : 918
    Points : 1 921
    Points
    1 921
    Par défaut
    T f(void) n'est qu'un raccourci de retrocompatibilité pour T f()

    tu ne peux pas passer de type void de cette façon, il faut que tu spécialise ton template.

  3. #3
    Membre éprouvé Avatar de cs_ntd
    Homme Profil pro
    Développeur .NET
    Inscrit en
    Décembre 2006
    Messages
    598
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Etats-Unis

    Informations professionnelles :
    Activité : Développeur .NET
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Décembre 2006
    Messages : 598
    Points : 1 215
    Points
    1 215
    Par défaut
    Merci de ta réponse rapide

    Que f(void) soit "un raccourci de retrocompatibilité" pour f(), pourquoi pas, mais je ne vois qaund même pas la raison profonde qui m'empeche de faire ça enfin bon

    Et après ba... spécialiser mon template je sais pas trop comment faire la.

    Le principe est que j'ai besoin d'une classe qui contient un pointeur sur une fonction, pour laquelle je ne connais ni le type de retour, ni le type du paramètre.

    Du coup, spécialiser pour <void, void>, c'est possible, mais j'oublie de ce fait tous les autres cas (quand T1 != void).

    A moins que je puisse avoir une syntaxe de ce genre la : C<T><void>, et spécialiser uniquement quand la 2ème partie est à void? Mais je ne vois pas comment...

  4. #4
    Membre éprouvé Avatar de cs_ntd
    Homme Profil pro
    Développeur .NET
    Inscrit en
    Décembre 2006
    Messages
    598
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Etats-Unis

    Informations professionnelles :
    Activité : Développeur .NET
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Décembre 2006
    Messages : 598
    Points : 1 215
    Points
    1 215
    Par défaut
    Ok j'ai raconté n'importe quoi juste avant
    Donc tout betement en faisant :
    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
     
    template<class T1, class T2>
    class D
    {
        public:
        typedef T1 (*Fptr)(T2);
        Fptr fptr;
    };
     
    template<class T>
    class D<T,void>
    {
        public:
        typedef T (*Fptr)();
        Fptr fptr;
    };
     
    int main()
    {
        D<void,void> c;
        return 0;
    }
    ça à l'air de marcher (du moins ça compile). En fait c'est pas si affreux .

    N'empeche. Ca aurait été plus simple si j'avais pu directement passer le type void

    Merci de la suggestion, je vais passer ça en résolu vu que j'arrive à faire plus ou moins ce que je veux...

  5. #5
    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
    Salut,
    Citation Envoyé par cs_ntd Voir le message
    N'empeche. Ca aurait été plus simple si j'avais pu directement passer le type void
    C'est parfois plus simple de passer par une classe trait pour construire ton type et ne pas avoir à faire de spécialisation partielle de ta classe de départ si elle contient plus de code :
    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
    namespace details
    {
        template<typename T1, typename T2>
        struct c_td_trait
        {
            typedef T1 (*type)(T2);
        };
        template<typename T1>
        struct c_td_trait<T1,void>
        {
            typedef T1 (*type)(void);
        };
    }
    template<class T1, class T2>
    class C
    {
     
    public:
        //T2 à la place de void pour le type de l'argument
        typedef typename details::c_td_trait<T1,T2>::type Fptr;
        Fptr fptr;
    };

  6. #6
    Membre éprouvé Avatar de cs_ntd
    Homme Profil pro
    Développeur .NET
    Inscrit en
    Décembre 2006
    Messages
    598
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Etats-Unis

    Informations professionnelles :
    Activité : Développeur .NET
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Décembre 2006
    Messages : 598
    Points : 1 215
    Points
    1 215
    Par défaut
    Salut, merci de tes précisions.

    Du coup c'est exactement ce que j'ai fait, comme j'avais pas envie de réécrire 2 fois ma classe...

    Par contre je ne savais pas que ça portait un nom spécial cette "technique" (classe trait c'est ça ?).

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    typedef typename details::c_td_trait<T1,T2>::type Fptr;
    Saurais tu me dire pourquoi il faut ajouter typename ? Je l'avais pas mis au début, le compilo ma dit qu'il fallait le mettre.
    Je l'ai mis et ça a marché mais je sais pas pourquoi ^^

  7. #7
    Rédacteur/Modérateur
    Avatar de JolyLoic
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Août 2004
    Messages
    5 463
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 50
    Localisation : France, Yvelines (Île de France)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Août 2004
    Messages : 5 463
    Points : 16 213
    Points
    16 213
    Par défaut
    Citation Envoyé par cs_ntd Voir le message
    Saurais tu me dire pourquoi il faut ajouter typename ?
    http://cpp.developpez.com/faq/cpp/?p...LATES_typename

  8. #8
    Membre éprouvé Avatar de cs_ntd
    Homme Profil pro
    Développeur .NET
    Inscrit en
    Décembre 2006
    Messages
    598
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Etats-Unis

    Informations professionnelles :
    Activité : Développeur .NET
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Décembre 2006
    Messages : 598
    Points : 1 215
    Points
    1 215
    Par défaut
    Ah ! merci ^^

    Faudra que je la lise entier un jour cette FAQ ^_^'

  9. #9
    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
    Salut,
    Citation Envoyé par cs_ntd Voir le message
    Par contre je ne savais pas que ça portait un nom spécial cette "technique" (classe trait c'est ça ?).
    Un peu de lecture : Présentation des classes de Traits et de Politiques en C++
    par Alp Mestan

  10. #10
    Membre éprouvé Avatar de cs_ntd
    Homme Profil pro
    Développeur .NET
    Inscrit en
    Décembre 2006
    Messages
    598
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Etats-Unis

    Informations professionnelles :
    Activité : Développeur .NET
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Décembre 2006
    Messages : 598
    Points : 1 215
    Points
    1 215
    Par défaut
    J'ai tout lu, merci bien

    Et maintenant j'ai envie d'en mettre partout

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

Discussions similaires

  1. Réponses: 5
    Dernier message: 14/07/2010, 10h34
  2. Réponses: 7
    Dernier message: 22/06/2008, 00h05
  3. Réponses: 11
    Dernier message: 18/02/2007, 15h37
  4. Réponses: 14
    Dernier message: 16/05/2006, 11h26
  5. une url comme argument d'une fonction
    Par khayyam90 dans le forum Général JavaScript
    Réponses: 3
    Dernier message: 18/10/2004, 20h15

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