Why does `std::function` can accept pointer to member function while the first param of `Args...` is passed by value?

Viewed 49

Suppose we have a class Foo as follows:

struct Foo
{
    int x = 100;
    void print()
    {
        std::cout << x << std::endl;
    }
};

Obviously we can use std::function to wrap Foo::print as follows:

std::function<void(Foo*)> f(&Foo::print);
Foo bar;
f(&bar);             // Output 100

// or

std::function<void(Foo&)> f(&Foo::print);
Foo bar;
f(bar);              // Output 100

But once I found that use std::function<void(Foo)> instead of std::function<void(Foo*)> or std::function<void(Foo&)> still works:

// Neither Foo& nor Foo*

std::function<void(Foo)> f(&Foo::print);
Foo bar;
f(bar);              // Still output 100

Why does the last one works?

1 Answers

Member functions require a specific class object to invoke, and void(Foo) is just a function type that accepts a copy of the Foo class.

So f(bar) will copy bar and invoke the print() member function of its copy. If Foo is not copyable then it won't work.

Related