PHWinfo banniere

Titres
PORTAIL ANNUAIRE ARTICLES COMPARATEUR HÉBERGEURS DEVIS FORUMS RÉDUCTEUR D'URL
Précédent   PHWinfo > Autres forums > Forum Programmation & Conception > fr.comp.lang.c++ > Composition de function avec un "Non-Type Template Parameters"
S'inscrire FAQ Membres Recherche Messages du jour Marquer les forums comme lus
Composition de function avec un "Non-Type Template Parameters"

Réponse
 
LinkBack Outils de la discussion
Vieux 29/04/2008, 21h58   #1 (permalink)
plouf
Aucun Avatar
 
Messages: n/a
Hébergeur:
Par défaut Composition de function avec un "Non-Type Template Parameters"

Bonjour à tous,

J'ai essayé de faire un template qui donne la fonction composée de deux
fonction (sans utilisé de "functor"). Je suis arrivé à ça :

#include <iostream>

template<typename T1,typename T2,typename T3, T1 f1(T2), T2 f2(T3)>
T1 compose_fct(T3 arg)
{
return f1(f2(arg));
};

int twice(int a)
{
return 2*a;
}

int square(int a)
{
return a*a;
}

int main()
{
int (*sqr_tw)(int) = compose_fct<int,int,int,square,twice>;

std::cout << sqr_tw(4) << " :: " << square(twice(4)) << std::endl;
std::cout << sqr_tw(5) << " :: " << square(twice(5)) << std::endl;
std::cout << sqr_tw(6) << " :: " << square(twice(6)) << std::endl;

return 0;
}

(testé avec gcc 3.4.4 et VS2005)

Je trouve dommage d'être obligé de mettre ces 3 "int" dans
compose_fct<int,int,int,square,twice> alors qu'on a toutes les informations
nécéssaire avec le type des functions.

Personne n'a une idée pour améliorer ça ?

Seb
  Réponse avec citation
Vieux 30/04/2008, 08h54   #2 (permalink)
Ael Rowen Terence
Aucun Avatar
 
Messages: n/a
Hébergeur:
Par défaut Re: Composition de function avec un "Non-Type Template Parameters"


"plouf" <plouf79@yahoo.fr> a écrit dans le message de news:
LZLRj.106$yk.36@nntpserver.swip.net...
> Bonjour à tous,
>
> J'ai essayé de faire un template qui donne la fonction composée de deux
> fonction (sans utilisé de "functor"). Je suis arrivé à ça :
>
> #include <iostream>
>
> template<typename T1,typename T2,typename T3, T1 f1(T2), T2 f2(T3)>
> T1 compose_fct(T3 arg)
> {
> return f1(f2(arg));
> };
>
> int twice(int a)
> {
> return 2*a;
> }
>
> int square(int a)
> {
> return a*a;
> }
>
> int main()
> {
> int (*sqr_tw)(int) = compose_fct<int,int,int,square,twice>;
>
> std::cout << sqr_tw(4) << " :: " << square(twice(4)) << std::endl;
> std::cout << sqr_tw(5) << " :: " << square(twice(5)) << std::endl;
> std::cout << sqr_tw(6) << " :: " << square(twice(6)) << std::endl;
>
> return 0;
> }
>
> (testé avec gcc 3.4.4 et VS2005)
>
> Je trouve dommage d'être obligé de mettre ces 3 "int" dans
> compose_fct<int,int,int,square,twice> alors qu'on a toutes les
> informations nécéssaire avec le type des functions.
>
> Personne n'a une idée pour améliorer ça ?



Très intéressant.
Bravo !


  Réponse avec citation
Vieux 30/04/2008, 13h49   #3 (permalink)
Michael DOUBEZ
Aucun Avatar
 
Messages: n/a
Hébergeur:
Par défaut Re: Composition de function avec un "Non-Type Template Parameters"

plouf a écrit :
> Bonjour à tous,
>
> J'ai essayé de faire un template qui donne la fonction composée de
> deux fonction (sans utilisé de "functor"). Je suis arrivé à ça :

[snip]
> int (*sqr_tw)(int) = compose_fct<int,int,int,square,twice>;

[snip]
> Je trouve dommage d'être obligé de mettre ces 3 "int" dans
> compose_fct<int,int,int,square,twice> alors qu'on a toutes les
> informations nécéssaire avec le type des functions.
>
> Personne n'a une idée pour améliorer ça ?


Pas vraiment. Spécialiser sur R(*T)(P) est spécialiser sur une valeur;
pour avoir une valeur, on est bien obligé d'avoir un type.

Imagine que square ait plusieurs spécialisations:
double square(double)
float square(float)
int square(int)

Se contenter de:
compose_fct<square,twice>
ne permettrait pas de choisir la bonne valeur.

--
Michael
  Réponse avec citation
Vieux 30/04/2008, 21h15   #4 (permalink)
plouf
Aucun Avatar
 
Messages: n/a
Hébergeur:
Par défaut Re: Composition de function avec un "Non-Type Template Parameters"

Michael DOUBEZ a écrit :
....
>
> Pas vraiment. Spécialiser sur R(*T)(P) est spécialiser sur une valeur;
> pour avoir une valeur, on est bien obligé d'avoir un type.
>
> Imagine que square ait plusieurs spécialisations:
> double square(double)
> float square(float)
> int square(int)
>
> Se contenter de:
> compose_fct<square,twice>
> ne permettrait pas de choisir la bonne valeur.
>


Ah oui, je n'avais pas pensé à ça. C'est donc logique qu'on ne puisse pas
simplifier plus.
Merci.

Seb
  Réponse avec citation
Vieux 01/05/2008, 03h31   #5 (permalink)
Fabien LE LEZ
Aucun Avatar
 
Messages: n/a
Hébergeur:
Par défaut Re: Composition de function avec un "Non-Type Template Parameters"

30 Apr 2008 14:49:46 +0200, Michael DOUBEZ :

>Imagine que square ait plusieurs spécialisations:
>double square(double)
>float square(float)
>int square(int)


Mais en l'occurence, on n'en a qu'une. Le compilateur est capable de
déduire les types qui vont bien dans un tel cas.

Exemple : le code ci-dessous est parfaitement valide, et cesse de
l'être quand on enlève les "//".


int square (int);
//double square (double);

template <class Resultat, class Argument>
void F (Resultat (*fct) (Argument))
{}

int main()
{
F (square);
}



  Réponse avec citation
Vieux 01/05/2008, 03h39   #6 (permalink)
Fabien LE LEZ
Aucun Avatar
 
Messages: n/a
Hébergeur:
Par défaut Re: Composition de function avec un "Non-Type Template Parameters"

On Tue, 29 Apr 2008 22:58:53 +0200, plouf <plouf79@yahoo.fr>:
>[...]


J'ai bien conscience que le code ci-dessous ne répond pas à la
question, mais c'est la seule solution que j'aie trouvé pour ne jamais
avoir à écrire les types dans le code client.



template <typename Resultat,
typename Intermediaire,
typename Argument>
class FoncteurCompose_t
{
public:
typedef Resultat (*Fonction1)(Intermediaire);
typedef Intermediaire (*Fonction2)(Argument);

FoncteurCompose_t (Fonction1 f1_, Fonction2 f2_)
: f1 (f1_), f2 (f2_) {}

Resultat operator () (Argument const& a) const
{ return f1(f2(a)); }

private:
Fonction1 f1;
Fonction2 f2;
};

template <typename Resultat,
typename Intermediaire,
typename Argument>
FoncteurCompose_t <Resultat, Intermediaire, Argument>
FoncteurCompose (Resultat (*f1)(Intermediaire),
Intermediaire (*f2)(Argument))
{
return FoncteurCompose_t <Resultat, Intermediaire, Argument>
(f1, f2);
}




int twice(int a)
{
return 2*a;
}

int square(int a)
{
return a*a;
}


#include <iostream>

template <class F> void Teste (F f)
{
std::cout << f(4) << " :: " << square(twice(4)) << std::endl;
std::cout << f(5) << " :: " << square(twice(5)) << std::endl;
std::cout << f(6) << " :: " << square(twice(6)) << std::endl;
}

int main()
{
Teste (FoncteurCompose (square, twice));
}

  Réponse avec citation
Vieux 01/05/2008, 03h53   #7 (permalink)
Fabien LE LEZ
Aucun Avatar
 
Messages: n/a
Hébergeur:
Par défaut Re: Composition de function avec un "Non-Type Template Parameters"

On Tue, 29 Apr 2008 22:58:53 +0200, plouf <plouf79@yahoo.fr>:
>[...]


J'ai bien conscience que le code ci-dessous ne répond pas à la
question, mais c'est la seule solution que j'aie trouvé pour ne jamais
avoir à écrire les types dans le code client.



template <typename Resultat,
typename Intermediaire,
typename Argument>
class FoncteurCompose_t
{
public:
typedef Resultat (*Fonction1)(Intermediaire);
typedef Intermediaire (*Fonction2)(Argument);

FoncteurCompose_t (Fonction1 f1_, Fonction2 f2_)
: f1 (f1_), f2 (f2_) {}

Resultat operator () (Argument const& a) const
{ return f1(f2(a)); }

private:
Fonction1 f1;
Fonction2 f2;
};

template <typename Resultat,
typename Intermediaire,
typename Argument>
FoncteurCompose_t <Resultat, Intermediaire, Argument>
FoncteurCompose (Resultat (*f1)(Intermediaire),
Intermediaire (*f2)(Argument))
{
return FoncteurCompose_t <Resultat, Intermediaire, Argument>
(f1, f2);
}




int twice(int a)
{
return 2*a;
}

int square(int a)
{
return a*a;
}


#include <iostream>

template <class F> void Teste (F f)
{
std::cout << f(4) << " :: " << square(twice(4)) << std::endl;
std::cout << f(5) << " :: " << square(twice(5)) << std::endl;
std::cout << f(6) << " :: " << square(twice(6)) << std::endl;
}

int main()
{
Teste (FoncteurCompose (square, twice));
}

  Réponse avec citation
Vieux 01/05/2008, 04h20   #8 (permalink)
Fabien LE LEZ
Aucun Avatar
 
Messages: n/a
Hébergeur:
Par défaut Re: Composition de function avec un "Non-Type Template Parameters"

On Tue, 29 Apr 2008 22:58:53 +0200, plouf <plouf79@yahoo.fr>:

> Je trouve dommage d'être obligé de mettre ces 3 "int" dans
>compose_fct<int,int,int,square,twice> alors qu'on a toutes les informations
>nécéssaire avec le type des functions.


J'ai trouvé le moyen d'éviter de spécifier ces trois "int"... à
condition de taper les noms des fonctions deux fois !
C'est le code le plus tordu que j'aie pondu depuis un bout de temps...



/* La fonction finale. Aux noms des identifiants près, il s'agit de
ton code. */

template <typename Resultat,
typename Intermediaire,
typename Argument,
Resultat f1 (Intermediaire),
Intermediaire f2 (Argument)>
Resultat compose_fct(Argument arg)
{
return f1(f2(arg));
};


/* Ici, on sépare les arguments templates "types" des arguments
templates "fonctions".
L'idée : puisque les deux fonctions sont des arguments templates, il
faut que les trois types soient déjà définis. La seule façon de faire,
c'est de mettre "GetF" dans une classe template. */

template <typename Resultat,
typename Intermediaire,
typename Argument>
struct Composeur_t
{
typedef Resultat (*Reponse) (Argument);

template <Resultat f1 (Intermediaire), Intermediaire f2 (Argument)>
Reponse GetF() const
{ return compose_fct
<Resultat, Intermediaire, Argument, f1, f2>; }
};


/* Le compilateur est capable de déduire automatiquement les
paramètres template pour une fonction, mais pas pour une classe. On
crée donc une fonction "er" qui crée un objet de type Composeur_t.
*/

template <typename Resultat,
typename Intermediaire,
typename Argument>
Composeur_t <Resultat, Intermediaire, Argument>
Composeur (Resultat (*f1)(Intermediaire),
Intermediaire (*f2)(Argument))
{
return Composeur_t <Resultat, Intermediaire, Argument>();
}



// Tes deux fonctions

int twice(int a)
{
return 2*a;
}

int square(int a)
{
return a*a;
}


// Le code utilisateur

int main()
{
typedef int (*fonction) (int);
fonction f= Composeur(square,twice).GetF<square,twice>();
}

  Réponse avec citation
Réponse


Outils de la discussion

Règles de messages
Vous ne pouvez pas créer de nouvelles discussions
Vous ne pouvez pas envoyer des réponses
Vous ne pouvez pas envoyer des pièces jointes
Vous ne pouvez pas modifier vos messages

Les balises BB sont activées : oui
Les smileys sont activés : oui
La balise [IMG] est activée : oui
Le code HTML peut être employé : non
Trackbacks are oui
Pingbacks are oui
Refbacks are oui


Fuseau horaire GMT +1. Il est actuellement 15h57.


Édité par : vBulletin® version 3.7.2
Copyright ©2000 - 2008, Jelsoft Enterprises Ltd.
Search Engine Friendly URLs by vBSEO 3.2.0 RC5 Tous droits réservés.
Version française #16 par l'association vBulletin francophone
PHWinfo est un site Éducation Sans Frontières
Ad Management by RedTyger
©Tous droits réservés par les parties respectives
Page generated in 0,16638 seconds with 16 queries