Bonjour à tous !
Je suis nouveau sur ce forum donc n'hésitez pas à me reprendre et à me signaler si je ne respecte pas toutes les règles .
J'utilise GCC version C++03. Je peux upgrader en C++11 ou 14 si nécessaire.
Je me pose un problème assez général, plutôt ambitieux .
- Je souhaite travailler avec des fonctions (fonctions ou foncteurs, à voir) template. Jusque là tout va bien :
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10 #include <iostream> #include <vector> using namespace std; template<typename T> T add(const T& a, const T& b) { return a+b; }- Je souhaite maintenant travailler avec des fonctions d'ordre supérieur (un modificateur) qui prendrait une ou deux fonctions template et "renverrait" une autre fonction template dérivée. Par exemple "cumulate" prendrait la fonction "add" et renverrait "cum_sum". Un truc du style :
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 /** Le modificateur cumulate prend une fonction binaire (add, multiply...) sous forme de pointeur. Il renvoie une fonction unaire qui permet l'accumulation de cette fonction entre les éléments d'un vecteur passé en entrée. */ template<typename T> T(*)(const vector<T>&) cumulate( vector<T> (*base_func)(const vector<T>&, const vector<T>&) ) { //Définition de la fonction dérivée T derived_func( const vector<T>& V) { result = V[0]; for(int i=1; i<V.size(); i++){ result = add<T>(result, V[i]); } return result; } return &derived_func; }
J'ai conscience que le code ci-dessus ne peut pas compiler (mises à part mes erreurs de syntaxe ), car le compilateur doit pouvoir "fixer" les types de la fonction avant toute utilisation. Néanmoins, je souhaite vraiment ne dériver la fonction qu'une seule fois et pouvoir utiliser la fonction dérivée générique dans plein de contextes différents.
J'imagine plein d'autres modificateurs comme la composition, la négation, la curryfication (binding)... Mais mon objet de base reste la fonction "templatisée" et je souhaite retarder la spécialisation au maximum, càd seulement lorsque cette fonction est appelée. De la méta-prog en somme ... Je suis déjà allé voir du côté de la STL qui propose ce genre de modificateurs sur les foncteurs (compose, bind...) mais là encore le foncteur doit être "spécialisé" avant de pouvoir passer comme argument du modificateur.
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14 int main(){ template<typename T> // C'est louche... T(*)(const vector<T>&) cumsum = cumulate(add) // Aïe Aïe Aïe !!! vector<int> V_int(2) // 2 entiers vector<bool> V_bool(3) // 3 booléens vector<float> V_float(4) // 4 floattants /* ... Remplissage des vecteurs ... */ cout << *cumsum<int>(V_int) << endl; // Somme cumulée des deux entiers cout << *cumsum<bool>(V_bool) << endl; // Somme cumulée des trois booléens (donne le nombre de prédicats VRAIS) cout << *cumsum<float>(V_float) << endl; // Somme cumulée des quatre flottants }
Des idées ?
Partager