Bonjour,
Je suis dans le cas (simplifié) suivant :
Je ne maîtrise pas encore totalement la sémantique de mouvement, mais j'ai peur que ce code ne fonctionne pas comme je le voudrais : d'après moi, les arguments sont "déplacés" pour le premier bind, il ne sont alors plus disponibles pour le second.
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8 template<typename F1, typename F2, typename ... Args> std::pair<std::function<void()>, std::function<void()>> do_bind(F1&& f1, F2&& f2, Args&& ... args) { return make_pair( std::bind(std::forward<F1>(f1), std::forward<Args>(args)...), std::bind(std::forward<F2>(f2), std::forward<Args>(args)...) ); }
On peut le tester avec ce code :
... qui affiche 0 et 5, suggérant que le second membre de la paire a été initialisé en premier.
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 struct A { int i = 0; A() = default; A(int i) : i(i) {} A(const A& a) : i(a.i) {} A(A&& a) : i(a.i) { a.i = 0; } }; void some_func(const A& a) { std::cout << a.i << std::endl; } void some_other_func(const A& a) { std::cout << a.i << std::endl; } int main() { auto ret = do_bind(&some_func, &some_other_func, A(5)); ret.first(); ret.second(); }
Ma question est donc :
- que faut-il faire pour que les deux fonctions ainsi créées reçoivent toutes deux des arguments aussi bien "forwardés" que possible?
- quels sont les inconvénients de cette approche :
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7 template<typename F1, typename F2, typename ... Args> std::pair<std::function<void()>, std::function<void()>> do_bind(F1&& f1, F2&& f2, Args&& ... args) { auto fb1 = std::bind(std::forward<F1>(f1), args...); auto fb2 = std::bind(std::forward<F2>(f2), std::forward<Args>(args)...); return make_pair(std::move(fb1), std::move(fb2)); }
Je précise qu'un des buts de cette fonction est d'éviter à son utilisateur d'avoir à fournir deux fois une même série d'arguments.
Partager