Search code examples
c++c++11stdbind

Unable to std::bind member function


I've written the following class:

class SomeClass {
private:
    void test_function(int a, size_t & b, const int & c) {
        b = a + reinterpret_cast<size_t>(&c);
    }
public:
    SomeClass() {
        int a = 17;
        size_t b = 0;
        int c = 42;
        auto test = std::bind(&SomeClass::test_function, std::placeholders::_1, std::placeholders::_2, std::placeholders::_3);
        test(a, b, c);
    }
}

On its own, this code looks fine in the IDE (Visual Studio 2015) but when I try to compile it, I get the following errors:

Error   C2893   Failed to specialize function template 'unknown-type std::invoke(_Callable &&,_Types &&...)'    Basic Server    C:\Program Files (x86)\Microsoft Visual Studio 14.0\VC\include\type_traits  1441    
Error   C2672   'std::invoke': no matching overloaded function found    Basic Server    C:\Program Files (x86)\Microsoft Visual Studio 14.0\VC\include\type_traits  1441    

What am I doing wrong?

EDIT: I also wrote this version:

class SomeClass {
private:
    void test_function(int a, size_t & b, const int & c) {
        b = a + reinterpret_cast<size_t>(&c);
    }
public:
    SomeClass() {
        int a = 17;
        size_t b = 0;
        int c = 42;
        auto test = std::bind(&SomeClass::test_function, a, std::placeholders::_1, std::placeholders::_2);
        test(b, c);
    }
}

I get the exact same errors.


Solution

  • You're forgetting the fourth parameter to the std::bind and that is the instance on which you want to call a non-static member function. Since it doesn't operate on the (non-existent) class member data, I reckon it should be static, in which case you don't need an instance.

    That being said, if you want to bind to a non-static member function, you can do:

    auto test = std::bind(&SomeClass::test_function, this, std::placeholders::_1,
                          std::placeholders::_2, std::placeholders::_3);
    // you can also bind *this
    

    or (this does not make sense with no bound parameter - bind a, b, c if you like):

    auto test = std::bind(&SomeClass::test_function,
                          std::placeholders::_1, std::placeholders::_2,
                          std::placeholders::_3, std::placeholders::_4);
    test(this, a, b, c); // you can also pass a reference
    

    and stuff like that.