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 :

Meta programation : Fonction templates


Sujet :

C++

  1. #1
    Membre éprouvé
    Avatar de Zenol
    Homme Profil pro
    Étudiant
    Inscrit en
    Novembre 2004
    Messages
    812
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 34
    Localisation : France

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Novembre 2004
    Messages : 812
    Points : 1 054
    Points
    1 054
    Par défaut Meta programation : Fonction templates
    Bonsoir,

    Suite à la lecture du tutoriel d'initiation à la méta programation de Laurent, j'ai voulut ecrire une structure template pour boucler sur une fonction. Je me suis donc dit, si je veut pouvoir choisir la fonction, il faudrait que je done un pointeur de fonction à ma tructure, donc j'ai voulut faire :
    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 Ptr, int Start, int End>
    struct For
    {
    	static void Do()
    	{
    		Ptr();
    		For<Ptr, Start, End>::Do();
    	}
    };
     
    template <class Ptr, int N>
    struct For<Ptr, N, N>
    {
    	static void Do(){}
    };
     
    //Une fonction de teste
    inline void tst ()
    {
    	std::cout << "tst\n";
    }
    //Un apelle
    For<tst, 1, 4>;
    Comme vous vous en doutez, si je poste ici c'est que ca ne fonctione pas

    Donc, j'en suis venu à me demander si j'aurais commit une erreur de syntaxe, ou le cas contraire si le compilateur pouvais ou non considèrer un pointeur de fonction comme connu à la compilation?

  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 : 40
    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
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    template <class Ptr, ...
    Là tu attends un type, or toi tu veux passer un pointeur de fonction.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    template <void (*Ptr)(), ...
    ca ne fonctione pas
    La prochaine fois, pense à détailler un petit peu, on n'est pas tous dans la tête de ton compilo

  3. #3
    Membre éprouvé
    Avatar de Zenol
    Homme Profil pro
    Étudiant
    Inscrit en
    Novembre 2004
    Messages
    812
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 34
    Localisation : France

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Novembre 2004
    Messages : 812
    Points : 1 054
    Points
    1 054
    Par défaut
    Ah oui tout bête...

    Saufe que maintenant c'est l'apelle qui ne fonctione pas :/
    j'ai le droit à un joli
    (For<tst, 1, 4> | main.cpp:18: error: declaration does not declare anything

    J'en profite pour demander pourquoi la compilation de
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    template <signed int N>
    struct Fact
    {
    	enum
    	{
    		Value = N >= 0
    			? N * Fact<N-1>::Value
    			: -1 * Fact<-1*N>::Value
    	};
    };
    s'enbale? Normalement il devrait réagir "normalemen" mais j'ai le droit à une longue liste d'ereur de la forme
    Meta_Calc.h: In instantiation of `Fact<-0x000000001>':
    Meta_Calc.h:32: instantiated from `Fact<1>'
    main.cpp:17: instantiated from here
    Meta_Calc.h:32: error: incomplete type `Fact<1>' used in nested name specifier
    *Vraiment pas douer avec ces templattes*

  4. #4
    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 : 40
    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
    N'oublie pas que For<tst, 1, 4> est un type. L'appel, c'est :

    Pour la factorielle, je pense que le problème sera réglé lorsque tu auras une condition d'arrêt.
    Par ailleurs je ne suis pas sûr que la factorielle d'un nombre négatif soit définie.

  5. #5
    Membre éprouvé
    Avatar de Zenol
    Homme Profil pro
    Étudiant
    Inscrit en
    Novembre 2004
    Messages
    812
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 34
    Localisation : France

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Novembre 2004
    Messages : 812
    Points : 1 054
    Points
    1 054
    Par défaut
    Citation Envoyé par Laurent Gomila
    N'oublie pas que For<tst, 1, 4> est un type. L'appel, c'est :

    Pour la factorielle, je pense que le problème sera réglé lorsque tu auras une condition d'arrêt.
    Par ailleurs je ne suis pas sûr que la factorielle d'un nombre négatif soit définie.
    Faut que je m'y fasse à cette fasson étrange ^^'

    Pour la factoriel j'ai une condition d'aret : Fac<0> vaut 1.

    D'ailleur, si je suprime le (N > 0) ? ... : -1 * Fact<-1*N>::Value et en métent simplement N * Fact<N-1>::Value tout fonctione corectement (pour els nombre positife, avec les nombres négatife ca boucle sans s'arèter)

    Edit : Encore une bizarerie qui me surprend : J'ai oublier d'incrémenter le premier paramêtre template dans mon for, et le compilatuer ne m'a pas renvoiller d'ereur :o Il aurais dut rentrer dnas une boucle infini à la compilation, mais non il a réusi à déjouer le piège et à créer une boucle infini à l'éxecution O.O

  6. #6
    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 : 40
    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
    Si tu as une spécialisation pour N = 0 tu n'as pas besoin de tester N >= 0 dans ton calcul. En prenant N en tant qu'entier non signé tu éviterais aussi les erreurs dûes aux nombres négatifs.

    Pourquoi ne pas partir de la version que je propose dans mon tutoriel ?

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    template<unsigned int N> struct Factorielle
    {
        enum {Value = N * Factorielle<N - 1>::Value};
    };
    template<> struct Factorielle<0>
    {
        enum {Value = 1};
    };

  7. #7
    Membre éprouvé
    Avatar de Zenol
    Homme Profil pro
    Étudiant
    Inscrit en
    Novembre 2004
    Messages
    812
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 34
    Localisation : France

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Novembre 2004
    Messages : 812
    Points : 1 054
    Points
    1 054
    Par défaut
    Citation Envoyé par Laurent Gomila
    Si tu as une spécialisation pour N = 0 tu n'as pas besoin de tester N >= 0 dans ton calcul. En prenant N en tant qu'entier non signé tu éviterais aussi les erreurs dûes aux nombres négatifs.

    Pourquoi ne pas partir de la version que je propose dans mon tutoriel ?

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    template<unsigned int N> struct Factorielle
    {
        enum {Value = N * Factorielle<N - 1>::Value};
    };
    template<> struct Factorielle<0>
    {
        enum {Value = 1};
    };
    Parce que je veut justement pouvoir utiliser des nombres négatifes :/

  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 : 40
    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
    La fonction factorielle n'est pas définie pour les nombres négatifs, pourquoi veux-tu faire ça

  9. #9
    Membre éprouvé
    Avatar de Zenol
    Homme Profil pro
    Étudiant
    Inscrit en
    Novembre 2004
    Messages
    812
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 34
    Localisation : France

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Novembre 2004
    Messages : 812
    Points : 1 054
    Points
    1 054
    Par défaut
    Citation Envoyé par Laurent Gomila
    La fonction factorielle n'est pas définie pour les nombres négatifs, pourquoi veux-tu faire ça
    Pourquoi pas?

    Je fait ca pour m'entrainer à la méta programation, et si je tien tent que ca à coriger le problème ce n'est pas parce que j'ai un besoin vitale de pouvoir utiliser la fonction factoriel avec des nombres ngaife, mais parce que je veut comprendre pourquoi ca ne fonctione pas alors que rien ne semble poser problème...

  10. #10
    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 : 40
    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
    Le problème avec ta factorielle négative, c'est le test N >= 0. Le compilo ne va pas compiler seulement la branche qui correspond au résultat du test, mais les deux quoiqu'il arrive. Donc il tentera toujours de compiler pour N et -N, dont l'un provoque une boucle infinie.

    Pour ne compiler réellement que ce dont tu as besoin, il faudrait faire ceci :

    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
    template <signed int N, bool Positive> struct FactPositive;
     
    template <signed int N> struct Fact
    {
        enum {Value = FactPositive<N, (N >= 0)>::Value};
    };
     
    template <signed int N> struct FactPositive<N, true>
    {
        enum {Value = Factorielle<N>::Value};
    };
    template <signed int N> struct FactPositive<N, false>
    {
        enum {Value = Factorielle<-N>::Value};
    };
     
    template<unsigned int N> struct Factorielle
    {
        enum {Value = N * Factorielle<N - 1>::Value};
    };
    template<> struct Factorielle<0>
    {
        enum {Value = 1};
    };

  11. #11
    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 JC_Master
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    template <signed int N>
    struct Fact
    {
    	enum
    	{
    		Value = N >= 0
    			? N * Fact<N-1>::Value
    			: -1 * Fact<-1*N>::Value
    	};
    };
    s'enbale? Normalement il devrait réagir "normalemen" mais j'ai le droit à une longue liste d'ereur de la forme
    A la place de Fact<-1*N>, ne voulais tu pas écrire Fact<-1*N - 1> ?

  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 : 40
    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
    A la place de Fact<-1*N>, ne voulais tu pas écrire Fact<-1*N - 1> ?
    Je pense qu'il voulait juste écrire que la factorielle d'un N négatif c'est -1 * Fact(-N). La décrementation de N commence à l'itération suivante, lorsque N est positif.

  13. #13
    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
    Oups, pas réveillé...

  14. #14
    Membre éprouvé
    Avatar de Zenol
    Homme Profil pro
    Étudiant
    Inscrit en
    Novembre 2004
    Messages
    812
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 34
    Localisation : France

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Novembre 2004
    Messages : 812
    Points : 1 054
    Points
    1 054
    Par défaut
    Ah merci pour cette explication. Je vias esseiller de m'en souvenir ^^'

    Edit : Hrem, j'a un probème quand je passe des structures à des fonctions inline :s

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    Meta_Calc.h:41: error: partial specialization `_FactPositive<N, true>' of function template
    Meta_Calc.h:47: error: partial specialization `_FactPositive<N,  false>' of function template
    Meta_Calc.h:47: error: redefinition of `template<int N> double _FactPositive()'
    Meta_Calc.h:41: error: `template<int N> double _FactPositive()' previously declared here
    Meta_Calc.h:37: warning: inline function `double _FactPositive() [with int N = 10, bool Positive =  true]' used but never defined
    le problème se situ aux niveau des lignes
    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 <signed int N, bool Positive>
    inline double _FactPositive();
     
    template <signed int N>
    inline double _FactPositive<N, true>()
    {
    	return _Fact<N>();
    };
     
    template <signed int N>
    inline double _FactPositive<N, false>()
    {
    	return -_Fact<-N>();
    };
    Une explication silvouplait?

  15. #15
    Membre éprouvé
    Avatar de Zenol
    Homme Profil pro
    Étudiant
    Inscrit en
    Novembre 2004
    Messages
    812
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 34
    Localisation : France

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Novembre 2004
    Messages : 812
    Points : 1 054
    Points
    1 054
    Par défaut
    Je crois qu'aparement le compilatuer n'acepte pas que l'on ne done une valeur qu'à une partie des paramêtres template. Maleureusement je ne peut pas faire passer N comme argument de la fonction car je ne pourait plus l'utiliser pour apeler _Fact<N>() ... En fait je ne voi pas comment m'en sortir :s

  16. #16
    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 : 40
    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
    La spécialisation partielle de fonctions n'est effectivement pas permise (prévu pour le prochain standard ?)

    La seule solution, ce sont des fonctions statiques encapsulées dans des structures, qui elles peuvent être spécialisées partiellement.

  17. #17
    Membre éprouvé
    Avatar de Zenol
    Homme Profil pro
    Étudiant
    Inscrit en
    Novembre 2004
    Messages
    812
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 34
    Localisation : France

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Novembre 2004
    Messages : 812
    Points : 1 054
    Points
    1 054
    Par défaut
    Merci, ca à l'aire de fonctioner ^^

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

Discussions similaires

  1. Meta-programation, template et cast implicite
    Par Awakening dans le forum C++
    Réponses: 15
    Dernier message: 10/02/2012, 19h03
  2. Pointeur sur une fonction template
    Par Progs dans le forum Langage
    Réponses: 2
    Dernier message: 15/02/2006, 20h25
  3. Fonction template virtuelle... comment l'éviter ?
    Par :Bronsky: dans le forum Langage
    Réponses: 12
    Dernier message: 07/06/2005, 14h21
  4. fonctions template
    Par romeo9423 dans le forum Langage
    Réponses: 12
    Dernier message: 22/01/2005, 16h13
  5. Fonctions template+friend sous VC7
    Par patapetz dans le forum MFC
    Réponses: 12
    Dernier message: 24/09/2004, 11h16

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