Невозможно выполнить функцию-член std::bind

Я написал следующий класс:

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);
    }
}

Сам по себе этот код отлично выглядит в IDE (Visual Studio 2015), но когда я пытаюсь скомпилировать его, я получаю следующие ошибки:

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    

Что я делаю неправильно?

РЕДАКТИРОВАТЬ: Я также написал эту версию:

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);
    }
}

Я получаю точно такие же ошибки.

4 ответа

Решение

Вы забыли четвертый параметр std::bind и это тот экземпляр, в котором вы хотите вызвать нестатическую функцию-член. Так как он не работает с (несуществующими) данными члена класса, я считаю, что это должно быть staticв этом случае вам не нужен экземпляр.

При этом, если вы хотите связать с нестатической функцией-членом, вы можете сделать:

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

или (это не имеет смысла без связанного параметра - связать a, b, c если хочешь):

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

и тому подобное.

Когда используешь std::bind к функции-члену, this указатель должен функционировать (т.е. ему нужен доступ к экземпляру класса). Либо захвачен в качестве аргумента bind или как аргумент позже, когда вызывается связанный тип.

Например;

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

Вам нужно будет передать ссылку на объект, который SomeClass::test_function побежит дальше (скорее всего this). Cppreference описывает, как std::bind работает.

Другой вариант - сделать SomeClass::test_function статическая функция-член, которая не требует передачи экземпляра в связывание.

Когда вы используете bind захватить указатель на функцию-член, первый аргумент в результате bind объект должен быть чем-то, что относится к объекту подходящего типа. Так как вы привязаны к SomeClass::test_function вам нужен объект типа SomeClass применить его к, поэтому первый аргумент test должен быть объектом типа SomeClass или указатель на объект типа SomeClass, Для начала попробуйте назвать это так:

test(this, b, c);
Другие вопросы по тегам