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 :

CRTP de classes template


Sujet :

Langage C++

  1. #1
    Membre habitué
    Homme Profil pro
    Doctorant en Astrophysique
    Inscrit en
    Mars 2009
    Messages
    312
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Doctorant en Astrophysique
    Secteur : Enseignement

    Informations forums :
    Inscription : Mars 2009
    Messages : 312
    Points : 176
    Points
    176
    Par défaut CRTP de classes template
    Bonjour à tous.

    J'aimerai pouvoir faire du CRTP avec quelque chose d'assez particulier :
    - les classes dérivées seront des classes template
    - j'ai besoin que la classe de base connaisse les paramètres template des classes dérivées (je veux pouvoir travailler "normalement" avec ces types au sein de la classe de base)
    - (EDIT) certaines fonctions de ma classe de base vont devoir renvoyer des choses du type TCRTP<T0, TDIM0>, c'est à dire des classes dérivées TCRTP avec d'autres paramètres template (T0, TDIM0 au lieu de T, TDIM) (voir vis à vis de l'exemple après)



    Quelle est la bonne façon de concevoir une telle chose ?

    J'ai essayé la chose 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
     
     
    template<template<class T, unsigned int TDIM> class TCRTP> class NAbstract
    {
        T _data[TDIM];
    };
     
    template<typename T, unsigned int TDIM> class NArray : NAbstract< NArray<T, TDIM> >
    {
     
    };
     
    template<typename T, unsigned int TDIM> class NVector : NAbstract< NVector<T, TDIM> >
    {
     
    };
    mais ça ne compile pas :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    main.cpp|5|error: 'T' does not name a type|
    main.cpp|8|error: type/value mismatch at argument 1 in template parameter list for 'template<template<class T, unsigned int TDIM> class TCRTP> class NAbstract'|
    main.cpp|8|error:   expected a class template, got 'NArray<T, TDIM>'|
    main.cpp|13|error: type/value mismatch at argument 1 in template parameter list for 'template<template<class T, unsigned int TDIM> class TCRTP> class NAbstract'|
    main.cpp|13|error:   expected a class template, got 'NVector<T, TDIM>'|
    Merci beaucoup

  2. #2
    screetch
    Invité(e)
    Par défaut
    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<class TCRTP> class NAbstract
    {
        typename TCTRP::value_type _data[TCTRP::dim];
    };
     
    template<typename T, unsigned int TDIM> class NArray : NAbstract< NArray<T, TDIM> >
    {
     typedef T value_type;
     enum { dim = TDIM };
    };
     
    template<typename T, unsigned int TDIM> class NVector : NAbstract< NVector<T, TDIM> >
    {
     typedef T value_type;
     enum { dim = TDIM }; 
    };

  3. #3
    Membre habitué
    Homme Profil pro
    Doctorant en Astrophysique
    Inscrit en
    Mars 2009
    Messages
    312
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Doctorant en Astrophysique
    Secteur : Enseignement

    Informations forums :
    Inscription : Mars 2009
    Messages : 312
    Points : 176
    Points
    176
    Par défaut
    Bonjour.

    Quand je déclare un NArray<double, 3> avec ce code (d'ailleurs il y a une inversion de lettres TCRTP <-> TCTRP), g++ 4.6.2 me renvoie :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    error: no type named 'value_type' in 'class NArray<double, 3u>'

  4. #4
    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
    Le seul problème que je vois, c'est qu'il manque public, mais normalement gcc donne un message d'erreur plus clair dans ce cas (disant que le membre est privé ou protégé, pas qu'il n'existe pas).
    Les MP ne sont pas là pour les questions techniques, les forums sont là pour ça.

  5. #5
    Membre habitué
    Homme Profil pro
    Doctorant en Astrophysique
    Inscrit en
    Mars 2009
    Messages
    312
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Doctorant en Astrophysique
    Secteur : Enseignement

    Informations forums :
    Inscription : Mars 2009
    Messages : 312
    Points : 176
    Points
    176
    Par défaut
    Non, même avec le public, ça ne compile 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
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    #include <iostream>
     
    template<class TCRTP> class NAbstract
    {
        public:
            typename TCRTP::value_type _data[TCRTP::dim];
    };
     
    template<typename T, unsigned int TDIM> class NArray : NAbstract< NArray<T, TDIM> >
    {
        public:
            typedef T value_type;
            enum { dim = TDIM };
    };
     
    template<typename T, unsigned int TDIM> class NVector : NAbstract< NVector<T, TDIM> >
    {
        public:
            typedef T value_type;
            enum { dim = TDIM };
    };
     
    int main(int argc, char *argv[])
    {
        NArray<double, 3> x;
        return 0;
    }
    g++ 4.6.2 :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    error: no type named 'value_type' in 'class NArray<double, 3u>'

  6. #6
    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
    Oops, le type est incomplet... il faut passer le template et les paramètres individuellement. La solution de iammilind sur SO est la bonne voie. Je la recopie ici.

    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 T, unsigned int TDIM, template<class, unsigned int> class TCRTP>
    class NAbstract
    {
      T _data[TDIM];
    };
     
    template<typename T, unsigned int TDIM>
    class NArray : NAbstract< T, TDIM, NArray >
    {
    };
     
    template<typename T, unsigned int TDIM>
    class NVector : NAbstract< T, TDIM, NVector >
    {
    };
    Les MP ne sont pas là pour les questions techniques, les forums sont là pour ça.

  7. #7
    screetch
    Invité(e)
    Par défaut
    Ah mince ca ne marche pas pour la recursion comme ca puisque le type n'est pas complet, je m'a gouré
    sinon, je partais sur la solution de Jean-Marc.

  8. #8
    Membre habitué
    Homme Profil pro
    Doctorant en Astrophysique
    Inscrit en
    Mars 2009
    Messages
    312
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Doctorant en Astrophysique
    Secteur : Enseignement

    Informations forums :
    Inscription : Mars 2009
    Messages : 312
    Points : 176
    Points
    176
    Par défaut
    Yes !
    Merci beaucoup.

    Le code suivant fonctionne (la fonction test est ce qui m'intéressait surtout) et je pense que ça va me permettre de faire tout ce que je voulais :

    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
    #include <iostream>
     
    template<class T, unsigned int TDIM, template<class, unsigned int> class TCRTP>
    class NAbstract
    {
        public:
            NAbstract() : _data{} {;}
            ~NAbstract() {;}
            TCRTP<int, TDIM> test() {return TCRTP<int, TDIM>();}
            T _data[TDIM];
    };
     
    template<typename T, unsigned int TDIM>
    class NArray : public NAbstract< T, TDIM, NArray >
    {
        public:
            NArray() {;}
            ~NArray() {;}
    };
     
    template<typename T, unsigned int TDIM>
    class NVector : public NAbstract< T, TDIM, NVector >
    {
        public:
            NVector() {;}
            ~NVector() {;}
    };
     
    int main(int argc, char *argv[])
    {
        NArray<double, 3> x;
        x.test();
        return 0;
    }
    Certaines personnes évoquent cependant la relative "dangerosité" de passer des paramètres template en double, qui pourrait causer d'éventuels accidents. Y-aurait-il une autre méthode ou pensez vous que celle-ci est très bien ?

Discussions similaires

  1. Problème de classes template + CRTP
    Par Kaluza dans le forum Langage
    Réponses: 20
    Dernier message: 05/08/2012, 10h46
  2. Trouver le Type d'une classe template dynamiquement ?
    Par Serge Iovleff dans le forum Langage
    Réponses: 3
    Dernier message: 23/09/2005, 16h48
  3. [DLL/classe template] problème de link
    Par Bob.Killer dans le forum C++
    Réponses: 7
    Dernier message: 31/08/2005, 18h56
  4. Class template hérité
    Par Azharis dans le forum Langage
    Réponses: 4
    Dernier message: 24/06/2005, 22h03
  5. Réponses: 6
    Dernier message: 06/10/2004, 12h59

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