Bonjour,

Je suis dans le cas (simplifié) suivant :
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)...)
    );
}
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.

On peut le tester avec ce code :
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();
}
... qui affiche 0 et 5, suggérant que le second membre de la paire a été initialisé en premier.

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.