Fonction apply / template

pointejb Messages postés 8 Date d'inscription lundi 1 mars 2004 Statut Membre Dernière intervention 6 mai 2004 - 3 mai 2004 à 17:27
pointejb Messages postés 8 Date d'inscription lundi 1 mars 2004 Statut Membre Dernière intervention 6 mai 2004 - 6 mai 2004 à 11:21
Bonjour à tous,

Je cherche un moyen d'implémenter une fonction de type 'apply' qui prendrait en parametres une fonction et ses arguments et qui aurait comme but d'appliquer cette fonction à ses arguments.

Exemple:

int specificFunctionToA(A* the_A)
{
//code spécifique à A
}

int specificFunctionToB(B* the_B)
{
//code spécifique à B
}

A* ptrA = new A();
B* ptrB = new B();

// Voici les appels possible à la fonction que je souhaite implémenter
int resultA = functionApply(specificFunctionToA,ptrA);
int resultB = functionApply(specificFunctionToB,ptrB);

Je cherche une fonction de type apply qui puisse prendre un type de fonction donné mais n'importe quel type d'arguments.

J'essai avec les templates et les pointeurs de membres de classe mais ça bloque à l'édition de liens et je pense que je fais fausse route dans mon implémentation.

Mon but est d'avoir une fonction de type apply pour gérer des exceptions et codes retours qui sont levés par les fonctions spécifiques:

template<typename T1, typenameT2> int functionApply(T1 specificFunctionToX,T2 X)
{
//Ici du code ....
try
{
int result = (specificFunctionToX)(X);
}
catch(e1& e)
{
cout<<"On a l'exception e1"<<endl;
//Ici du code propre à e1 ...
}
catch(e2& e)
{
cout<<"On a l'exception e2"<<endl;
//Ici du code propre à e2 ...
}
catch(e3& e)
{
cout<<"On a l'exception e3"<<endl;
//Ici du code propre à e3 ...
}

//Ici encore du code

}

Est-ce que je suis dans la bonne voie ?
Quelqu'un aurait-il une solution ?

Merci d'avance à ceux qui ont une idée.

"La vie, c'est comme une boite de chocolat..."

7 réponses

cs_djl Messages postés 3011 Date d'inscription jeudi 26 septembre 2002 Statut Membre Dernière intervention 27 novembre 2004 7
3 mai 2004 à 20:38
tu ve faire un truc comme ca?

#include

struct A
{
};

struct B
{
};

int specificFunctionToA(A* the_A)
{
//code spécifique à A
}

int specificFunctionToB(B* the_B)
{
//code spécifique à B
}

template <class T> int apply( int(*f)(T), T t)
{
return (*f)(t);
}

int main()
{
A a;
B b;
apply(specificFunctionToA,&a);
apply(specificFunctionToB,&b);
}
0
pointejb Messages postés 8 Date d'inscription lundi 1 mars 2004 Statut Membre Dernière intervention 6 mai 2004
4 mai 2004 à 11:40
C'est effectivement un truc comme ça.
En fait j'avais en plus un probleme de contravariance parce que je veux mettre cette fonction apply comme méthode d'une classe supérieure et la faire hériter dans les classe descendantes. J'ai trouvé une solution (similaire à la tienne) en contournant ce principe mais je crains que cela risque de core dumper un moment ou un autre.
La solution que j'ai trouvée est la suivante :

class SuperiorClass
{

public:

template<typename T1,typename T2, class T3>
int SuperiorClass::apply(T1 the_operation,
T2 the_para,
T3* the_class)
{

try
{
return (the_class->*Operation)(Para);
}
catch(CORBA::UserException& ex)
{
//....
}
}

//....

}

class InferiorClass : public SuperiorClass
{

public:
InferiorClass::InferiorClass(){a new A();b new B();}

int InferiorClass::specificFunctionToA(A* the_A)
{
//code spécifique à A
}

int InferiorClass::specificFunctionToB(B* the_B)
{
//code spécifique à B
}

private:

A* a;
B* b;

void InferiorClass::start()
{
int resultA = apply(specificFunctionToA,a,this);
int resultB = apply(specificFunctionToB,b,this);
}
0
cs_djl Messages postés 3011 Date d'inscription jeudi 26 septembre 2002 Statut Membre Dernière intervention 27 novembre 2004 7
4 mai 2004 à 20:56
oui ca risque sans destructeur/operateur =/constructeur copie
...

pas la peine de specifier InferiorClass:: dans le corps de la classe et le this serait pas inutile quand tu appelle apply ?

pourquoi tu met pas tout simplement apply en virtuelle ? c'est pas ce que tu ve faire au finale?
0
pointejb Messages postés 8 Date d'inscription lundi 1 mars 2004 Statut Membre Dernière intervention 6 mai 2004
5 mai 2004 à 12:07
Je ne l'ai pas spécifié mais j'ai bien un destructeur spécifique où je fais un delete des new que j'ai fait.
Je n'ai pas besoin d'opérateurs de classe comme = ni de constructeur par copie puique je ne m'en sers pas.
Le this est obligatoire car je ne peux pas déclarer une methode template en virtuelle (du moins d'après ce que j'ai lu et ce que g++ me dit).
Comme je veux que le template apply ait les mêmes propriétés qu'une methode virtuelle à savoir que dans apply si je veux utiliser une méthode de la classe InferiorClass qui est une redéfinition d'une méthode de la classe SuperiorClass, il faut soit que apply soit virtuelle (ce que je ne peux pas faire), soit que je spécifie explicitement la méthode que je désire utiliser (ce que je fais avec le pointeur this).
0

Vous n’avez pas trouvé la réponse que vous recherchez ?

Posez votre question
pointejb Messages postés 8 Date d'inscription lundi 1 mars 2004 Statut Membre Dernière intervention 6 mai 2004
5 mai 2004 à 12:08
Je ne l'ai pas spécifié mais j'ai bien un destructeur spécifique où je fais un delete des new que j'ai fait.
Je n'ai pas besoin d'opérateurs de classe comme = ni de constructeur par copie puique je ne m'en sers pas.
Le this est obligatoire car je ne peux pas déclarer une methode template en virtuelle (du moins d'après ce que j'ai lu et ce que g++ me dit).
Comme je veux que le template apply ait les mêmes propriétés qu'une methode virtuelle à savoir que dans apply si je veux utiliser une méthode de la classe InferiorClass qui est une redéfinition d'une méthode de la classe SuperiorClass, il faut soit que apply soit virtuelle (ce que je ne peux pas faire), soit que je spécifie explicitement la méthode que je désire utiliser (ce que je fais avec le pointeur this).
0
cs_djl Messages postés 3011 Date d'inscription jeudi 26 septembre 2002 Statut Membre Dernière intervention 27 novembre 2004 7
5 mai 2004 à 20:56
a ba oui tien, je vien de voir pour le virtuelle, desole

sinon pour le this je pense à un truc, genre en utilisant le cast classe mere -> classe fille, enfin je vais voir

sinon quand tu a une classe ou par exemple tu a des membre qui sont des pointeures que tu alloue dans le constructeur, c'est une regle de securité que de redefinir l'operateur = et le constructeur par copie

parce que le jour ou tu fera

InferiorClass a;
InferiorClass b=a;

ou

InferiorClass c;
c=a;

ou n'importe quel passage/retour par copie, difficile de dir ce qui se passera mai gros plantage assuré

bref, on appel ca generalement la regle de 3 (constructeur par copie/operateur =/destructeur) et on dit alors que ta classe est canonique
0
pointejb Messages postés 8 Date d'inscription lundi 1 mars 2004 Statut Membre Dernière intervention 6 mai 2004
6 mai 2004 à 11:21
Pour le this, j'ai pas réussi à trouver autre chose qui marche à cause du pointeur de membre que j'utilise dans la fonction appply.
En tous cas si tu as une idée je suis preneur.

C'est dommage qu'il n'y ait pas de notion de typage fort et dynamique en c++ (comme en Ocaml) parce que ca simplifirait les choses.

Sinon pour ce qui est de faire une classe canonique comme dans les règles de l'art, c'est clair que pour être propre et rigoureux dans mes dev il faudrait que je le fasse mais c'est pas faisable pour une raison de temps par rapport à ce que cela m'apporterait.
J'ai dans mes dev des arbres de classes contenant plusieurs dizaines de classes dont les membres sont des pointeurs, ce qui reviendrait à implémenter des constructeur par copie et opérateur = pour toutes.

A plus...
0
Rejoignez-nous