简体   繁体   中英

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.

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.

You will need to pass in the reference to the object that SomeClass::test_function will run on (most likely this ). Cppreference describes how std::bind works.

Another option is to make SomeClass::test_function a static member function which requires no instance to be passed into bind.

When using std::bind to a member function, the this pointer needs to feature (ie it needs access to an instance of the class). Either captured as an argument to the bind or as an argument later when the bound type is called.

For example;

auto test = std::bind(&SomeClass::test_function, this, std::placeholders::_1, std::placeholders::_2, std::placeholders::_3);
test(a, b, c);

When you use bind to capture a pointer to member function, the first argument to the resulting bind object has to be something that refers to an object of a suitable type. Since you're binding to SomeClass::test_function you need an object of type SomeClass to apply it to, so the first argument to test has to be an object of type SomeClass or a pointer to an object of type SomeClass . For starters, try calling it like this:

test(this, b, c);

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM