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 :

forward declaration sous template


Sujet :

Langage C++

  1. #1
    Membre éclairé
    Homme Profil pro
    Game Graphics Programmer
    Inscrit en
    Août 2006
    Messages
    408
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Allemagne

    Informations professionnelles :
    Activité : Game Graphics Programmer
    Secteur : High Tech - Multimédia et Internet

    Informations forums :
    Inscription : Août 2006
    Messages : 408
    Par défaut forward declaration sous template
    J'ai "découvert" un truc intéressant dont je n'aurais jamais cru que ca compile, mais ca fonctionne, donc j'aimerais savoir pourquoi.

    Voici une defintion de type template et sa concretisation dans un template namespace:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    template<class _tString>
    class _bar
    {
    public:
       _tString foo;
    };
     
    template<class _tString>
    struct B
    {
       typedef _tString String;
       typedef _bar<_tString> KBar;
    };
    Cela fonctionne, c'est normal, la définition du type _bar se trouvant avant sa concretisation.

    Mais ceci fonctionne aussi, alors que je ne m'y attendais 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
    template<class _tString>
    struct A
    {
       typedef _tString String;  
       class KFoo;
    };
     
     
    template<class _tString>
    class A<_tString>::KFoo
    {
    public:
       String bar;
    };
    Le code de test:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    void test()
    {
    	//A test
    	A<std::string>::KFoo foo;
    	foo.bar = "test";
    	std::cout << "A: << foo.bar << std::endl;
    	//B test
    	B<std::string>::KBar bar;
    	bar.foo = "test";
    	std::cout << "B: << bar.foo << std::endl;
    }
    Ca ne me donne aucune erreur, ni de warning, ce qui m'arrange au passage.
    Seulement j'aimerais savoir pourquoi ca fonctionne (testé sous GCC, VC8 et CodeWarrior Wii).

    Merci pour quelques eclaircissements.

  2. #2
    Rédacteur

    Avatar de Davidbrcz
    Homme Profil pro
    Ing Supaéro - Doctorant ONERA
    Inscrit en
    Juin 2006
    Messages
    2 307
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 33
    Localisation : Suisse

    Informations professionnelles :
    Activité : Ing Supaéro - Doctorant ONERA

    Informations forums :
    Inscription : Juin 2006
    Messages : 2 307
    Par défaut
    Regarde ce sujet: et en particulier ce message

    Ici c'est la même chose, des templates en plus.
    "Never use brute force in fighting an exponential." (Andrei Alexandrescu)

    Mes articles dont Conseils divers sur le C++
    Une très bonne doc sur le C++ (en) Why linux is better (fr)

  3. #3
    Membre éclairé
    Homme Profil pro
    Game Graphics Programmer
    Inscrit en
    Août 2006
    Messages
    408
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Allemagne

    Informations professionnelles :
    Activité : Game Graphics Programmer
    Secteur : High Tech - Multimédia et Internet

    Informations forums :
    Inscription : Août 2006
    Messages : 408
    Par défaut
    Ah, oui. Effectivement, c'est la même chose sous forme de template. Sans le template, j'aurais dit que ca fonctionne, mais avec le template, ca devient intéressant.

    Merci pour la réponse.

  4. #4
    Alp
    Alp est déconnecté
    Expert confirmé

    Avatar de Alp
    Homme Profil pro
    Inscrit en
    Juin 2005
    Messages
    8 575
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 36
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations forums :
    Inscription : Juin 2005
    Messages : 8 575
    Par défaut
    Bonjour,

    J'essaye de comprendre pourquoi tu ne pensais pas que ça fonctionnerait. Cela bloque peut-être ton raisonnement pour améliorer ta conception.

    Il faut bien que tu fois les paramètres d'une classe ou fonction template comme des ... paramètres, oui.
    Dis-toi que ce qui va se passer, c'est que lorsque tu vas instancier un template (càd fixer les paramètres pour créer une instance, ou alors sur une typedef), partout où il y a tes paramètres dans le code, cela va être remplacé par les paramètres donnés à l'instanciation. Et ce sera au final comme pour une classe normale.

    Un template crée une famille de classes ou une famille de fonctions, rien de plus

  5. #5
    Membre éclairé
    Homme Profil pro
    Game Graphics Programmer
    Inscrit en
    Août 2006
    Messages
    408
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Allemagne

    Informations professionnelles :
    Activité : Game Graphics Programmer
    Secteur : High Tech - Multimédia et Internet

    Informations forums :
    Inscription : Août 2006
    Messages : 408
    Par défaut
    C'était essentiellement la déclaration du string dans la classe qui me semblait faite pour me donner des erreus, mais vu que cela n'était pas le cas, j'étais étonné.

    Sinon, oui, en y refléchissant, cela doit fonctionner, vu que c'est la même que ceci mais en tant que template.

    Maintent, si je veux rajouter des fonctions, cela devra être sous cette forme, n'est-ce pas? Toujours dans l'en-tête:

    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
    template<class _tString>
    struct A
    {
       typedef _tString String;  
       class KFoo;
    };
     
     
    template<class _tString>
    class A<_tString>::KFoo
    {
    public:
       String bar;
     
       String do_foo(String& a)
       {	return a;   }
     
       String do_bar(String& a);
    };
     
    template<class _tString>
    A<_tString>::String A<_tString>::KFoo::do_bar(A<_tString>::String& a)
    {	return a	};
    Est-ce qu'il y a une facon pour simplifier cette définition de fonction, autre que l'utilisation abusive du preprocesseur?

    EDIT: oui, au lieu de A<_tString>::String je pourrais écrire _tString, ce serait syntaxiquement correct (la même chose), mais sémantiquement je ne veux pas utiliser de types autres que définis dans le namepsace.

  6. #6
    Alp
    Alp est déconnecté
    Expert confirmé

    Avatar de Alp
    Homme Profil pro
    Inscrit en
    Juin 2005
    Messages
    8 575
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 36
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations forums :
    Inscription : Juin 2005
    Messages : 8 575
    Par défaut
    Citation Envoyé par Kurisu Voir le message
    Maintent, si je veux rajouter des fonctions, cela devra être sous cette forme, n'est-ce pas?
    Oui.

    Citation Envoyé par Kurisu Voir le message
    Est-ce qu'il y a une facon pour simplifier cette définition de fonction, autre que l'utilisation abusive du preprocesseur?
    Toujours pas de robots pour écrire le code... On n'a que le préprocesseur pour faciliter la tâche. Mais commence par ne pas préfixer tes types par _ et ça sera pas mal
    Mais d'un autre côté, il suffit de s'habituer. Ce code ne me choque pas du tout (sauf que je ne vois pas pourquoi mettre le _ devant tString )

  7. #7
    Membre émérite Avatar de HanLee
    Profil pro
    Inscrit en
    Mai 2004
    Messages
    738
    Détails du profil
    Informations personnelles :
    Âge : 38
    Localisation : France, Rhône (Rhône Alpes)

    Informations forums :
    Inscription : Mai 2004
    Messages : 738
    Par défaut
    Si tu veux que ce soit plus court, écris tout dans la définition de la classe.

  8. #8
    Membre éclairé
    Homme Profil pro
    Game Graphics Programmer
    Inscrit en
    Août 2006
    Messages
    408
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Allemagne

    Informations professionnelles :
    Activité : Game Graphics Programmer
    Secteur : High Tech - Multimédia et Internet

    Informations forums :
    Inscription : Août 2006
    Messages : 408
    Par défaut
    HanLee> effectivement, mettre la définition de fonction dans la defintion de classe est une possibilité, mais je n'aime pas ca car ca rend le code illisible et trop ressemblant à Java.

    Alp> le "_" devant le nom de variable template, c'était pour souligner que c'est un paramètre du template, c'est tout. (Je sais que ca peut créer des complications lorsqu'on arrive à des noms prédéfinis par le compilateur, genre __cplusplus, par d'autres defines).

  9. #9
    Alp
    Alp est déconnecté
    Expert confirmé

    Avatar de Alp
    Homme Profil pro
    Inscrit en
    Juin 2005
    Messages
    8 575
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 36
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations forums :
    Inscription : Juin 2005
    Messages : 8 575
    Par défaut
    C'est surtout que c'est se compliquer la vie pour rien.
    Regarde les codes de Loki, Boost et autres si tu veux voir les "conventions" généralement utilisées et qui ont fait leurs preuves, sur ce point là

  10. #10
    Membre éclairé
    Homme Profil pro
    Game Graphics Programmer
    Inscrit en
    Août 2006
    Messages
    408
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Allemagne

    Informations professionnelles :
    Activité : Game Graphics Programmer
    Secteur : High Tech - Multimédia et Internet

    Informations forums :
    Inscription : Août 2006
    Messages : 408
    Par défaut
    oui, bon, j'avoue qu'écrire directement le code dans la classe template réduit énormement le travail d'écriture... mais avec ce que je veux faire, je ne sais pas si c'est facile à marier... cf. mon autre post sur la génération de noms de variables.

    En fait, c'est que je veux faire, d'une c'est une lib templatisée de lecture xml (sax), de deux, une lib d'algébre linéaire pour 3d (vecteurs, matrices, tout ca), templatisée pour être utilisé avec n'importe quel type de scalaire (entier, float, fixed,..), de trois, peut-être factorisé une autre lib pour fonctionner sans define de type de string préalable.

Discussions similaires

  1. Forward Declaration et template
    Par Zakaima dans le forum Débuter
    Réponses: 7
    Dernier message: 24/07/2012, 15h07
  2. Forward declaration avec templates
    Par gbdivers dans le forum Langage
    Réponses: 2
    Dernier message: 06/01/2011, 12h49
  3. Probleme de forward declaration
    Par porco dans le forum C++
    Réponses: 2
    Dernier message: 15/10/2006, 17h15
  4. Comment ça se declare sous linux
    Par frp31 dans le forum Réseau
    Réponses: 7
    Dernier message: 31/07/2006, 19h45
  5. has incomplete type,forward declaration of ,
    Par Pragmateek dans le forum C++
    Réponses: 12
    Dernier message: 22/07/2006, 15h03

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