How std :: bind works with member functions

I work with std::bind, but still don't understand, how it works when we use it with member class functions.

If we have the following function:

double my_divide (double x, double y) {return x/y;}

I understand the following lines of code perfectly:

auto fn_half = std::bind (my_divide,_1,2);               // returns x/2

std::cout << fn_half(10) << '\n';                        // 5

But now, with the following code in which we have a binding to a member function, I have a few questions.

struct Foo {
    void print_sum(int n1, int n2)
    {
        std::cout << n1+n2 << '\n';
    }
    int data = 10;
};

Foo foo;

auto f = std::bind(&Foo::print_sum, &foo, 95, _1);
f(5);
  • Why is the first argument a link? I would like a theoretical explanation.

  • The second argument is an object reference, and for me this is the hardest part to understand. I think because std::bindcontext is needed, am I right? It's always like that? Is there std::bindany implementation requiring a reference when the first argument is a member function?

+21
2

: " - ", " - ": & , .

, std::bind()

std::bind(my_divide, 2, 2)

. , . ,

std::bind(&my_divide, 2, 2)

std::bind() - , . double(*)(double, double). .

- , std::bind() -. &print_sum, -, .. void (Foo::*)(int, int). , .. & , - ( , ): - &.

, class, . , - . ++ -, ( , # , , , 10+ #).

std::bind() , - , , , , std::mem_fn() . - static , , [] .

-, . std::bind() std::bind() , .

std::bind(&Foo::print_sum, &foo, 95, _1)

&foo, foo ( Foo*) . std::bind() , -, , , (, std::reference_wrapper<Foo>) [] , .

, - . :

#include <iostream>

struct Foo {
    int value;
    void f() { std::cout << "f(" << this->value << ")\n"; }
    void g() { std::cout << "g(" << this->value << ")\n"; }
};

void apply(Foo* foo1, Foo* foo2, void (Foo::*fun)()) {
    (foo1->*fun)();  // call fun on the object foo1
    (foo2->*fun)();  // call fun on the object foo2
}

int main() {
    Foo foo1{1};
    Foo foo2{2};

    apply(&foo1, &foo2, &Foo::f);
    apply(&foo1, &foo2, &Foo::g);
}

apply() foo -. -, . ->* . .*, (, , ). - , , . std::bind() .

apply() &Foo::f, , f() . apply() &Foo::g , g() ( , , , , ).

+37

std:: bind docs:

bind( F&& f, Args&&... args ); f Callable, -. :

typedef  void (Foo::*FooMemberPtr)(int, int);

// obtain the pointer to a member function
FooMemberPtr a = &Foo::print_sum; //instead of just a = my_divide

// use it
(foo.*a)(1, 2) //instead of a(1, 2)

std::bind ( std::invoke ) . f Foo, Arg, , , Foo (bind(&Foo::print_sum, foo, ...) , Foo ) Foo, , .

, 1 2 , .

lambdas std::bind, :

auto f = [&](int n) { return foo.print_sum(95, n); }
+6

All Articles