Salut, trouvant les wrapper vraiment très pratique, j'ai décidé d'en faire quelque un dans mon framework à l'aide de la méta-programmation.
Mais je bloque ici (encore à cause de la redéfinition de fonctions template) mais cette fois-ci mes template sont des pointeurs sur fonction, j'ai crée une factory qui se charge d'instancier différent wrapper sur différent type de wrapper sur mes différent type de foncteurs.
Bref voici le code de ma factory :
Code cpp : 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
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65 template <> class FastDelegate<DefaultVoid> { public : FastDelegate () { delegate = nullptr; } bool operator!() { return delegate == nullptr; } template <typename O, typename F, typename ...A> FastDelegate(F f, O* object, A... args) { delegate = new FastDelegate7<F, O, A...>(f, object, args...); } template <typename F, typename ...A> FastDelegate(F f, A... args) { delegate = new FastDelegate6<F, A...>(f, args...); } template <typename O, typename ...A> FastDelegate(void(O::*f)(A...), O* object, A... args) { delegate = new FastDelegate2<O, A...>(f, object, args...); } template <typename O, typename ...A> FastDelegate(void(O::*f)(A...) const, O* object, A... args) { delegate = new FastDelegate2<O, A...>(f, object, args...); } template <typename O, typename D, typename ...A> FastDelegate(D* derived, A... args) { if (static_cast<O*>(derived)) { static_cast<FastDelegate2<O, A...>*>(delegate)->setParams(static_cast<O*>(derived), args...); } } template <typename ...A> FastDelegate(void(*f)(A...), A... args) { delegate = new FastDelegate0<A...>(f, args...); } void operator()() { (*delegate)(); } template <typename F, typename O, typename... A> void setFuncParams(O* object, A... args) { if (static_cast<FastDelegate6<F, O, A...>*>(delegate)) { static_cast<FastDelegate6<F, O, A...>*>(delegate)->setParams(object, args...); } } template <typename F, typename... A> void setFuncParams(A... args) { if (static_cast<FastDelegate7<F, A...>*>(delegate)) { static_cast<FastDelegate7<F, A...>*>(delegate)->setParams(args...); } } template <typename O, typename ...A> void setParams(O* object, A... args) { if (static_cast<FastDelegate2<O, A...>*>(delegate)) { static_cast<FastDelegate2<O, A...>*>(delegate)->setParams(object, args...); } } template <typename O, typename D, typename ...A> void setParams(D* derived, A... args) { if (static_cast<O*>(derived)) { static_cast<FastDelegate2<O, A...>*>(delegate)->setParams(static_cast<O*>(derived), args...); } } template<typename ...A> void setParams(A... args) { if (static_cast<FastDelegate0<A...>*>(delegate)) { static_cast<FastDelegate0<A...>*>(delegate)->setParams(args...); } } bool operator==(FastDelegate &other) { return delegate == other.delegate; } private : Delegate* delegate; };
Et je voudrais arriver à quelque chose comme ceci :
Code cpp : 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
25
26
27
28
29
30
31
32 class AClass { public : void aMemberFunction(std::string arg) { std::cout<<"a member function with argument : "<<arg<<std::endl; } int aMemberFunctionWithReturn(std::string arg) { std::cout<<"a member function with argument : "<<arg<<std::endl; return 1; } }; void aFunction (std::string arg) { std::cout<<"a function with argument : "<<arg<<std::endl; } int aFunctionWithReturn (std::string arg) { std::cout<<"a function with argument : "<<arg<<std::endl; return 1; } int main(int argc, char* args[]) { odfaeg::FastDelegate<void> anonymFunc([&](){std::cout<<"Coucou!"<<std::endl;}); anonymFunc(); odfaeg::FastDelegate<void> func(&aFunction, "arg1"); func(); odfaeg::FastDelegate<int> funcWithRet(&aFunctionWithReturn, "arg1"); int r = funcWithRet(); std::cout<<"return : "<<r<<std::endl; AClass anObj; odfaeg::FastDelegate<void> aMemberFunc(&AClass::aMemberFunction, &anObj, "arg1"); aMemberFunc(); return 0; }
Pas de soucis pour les fonctions non membre par contre j'ai une erreur en compilation pour les fonctions membre :
Le problème est qu'il me choisi le mauvais constructeur, il choisi celui pour créer le wrapper sur la fonction anonyme hors que ce n'est pas une fonction anonyme mais une fonction membre.
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11 ||=== Build: Debug in ODFAEG-DEMO (compiler: GNU GCC Compiler) ===| /home/laurent/Développement/Projets-c++/ODFAEG-DEMO/main.cpp|64|warning: "/*" within comment [-Wcomment]| /home/laurent/Développement/Projets-c++/ODFAEG-DEMO/main.cpp|99|warning: "/*" within comment [-Wcomment]| /usr/local/include/odfaeg/Core/signal.h||In instantiation of R odfaeg::callback(F, A ...) [with R = void; F = void (AClass::*)(std::basic_string<char>); A = {AClass*, const char*}]:| /usr/local/include/odfaeg/Core/signal.h|30|required from odfaeg::FastDelegate7<F, O, A>::FastDelegate7(F, O*, A ...) [with F = void (AClass::*)(std::basic_string<char>); O = AClass; A = {const char*}]| /usr/local/include/odfaeg/Core/signal.h|413|required from odfaeg::FastDelegate<void>::FastDelegate(F, O*, A ...) [with O = AClass; F = void (AClass::*)(std::basic_string<char>); A = {const char*}]| /home/laurent/Développement/Projets-c++/ODFAEG-DEMO/main.cpp|123|required from here| /usr/local/include/odfaeg/Core/signal.h|9|error: must use .* or ->* to call pointer-to-member function in func (...), e.g. (... ->* func) (...)| /usr/local/include/odfaeg/Core/signal.h|9|error: return-statement with a value, in function returning 'void' [-fpermissive]| ||=== Build failed: 2 error(s), 6 warning(s) (0 minute(s), 2 second(s)) ===|
J'ai bien essayé quelque chose comme ça mais cela ne marche pas :
Code cpp : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4 template <typename F, typename ...A, typename T, class = typename std::enable_if<!std::is_member_function_pointer<F>::value>::type> FastDelegate(F f, A... args, T) { delegate = new FastDelegate6<F, A...>(f, args...); }
C'est alors lorsque je veux construire le pointeur sur la fonction anonyme que ça ne marche plus, et je ne vois pas très bien comment procéder pour que le compilateur me choisisse le bon constructeur.
Merci d'avance pour vos réponses.
Partager