Как напрямую связать функцию-член с std :: function в Visual Studio 11?

Я могу легко связать функции-члены с std::function оборачивая их лямбда-выражением с предложением захвата.

class Class
{
Class()
{
Register([=](int n){ Function(n); });
}

void Register(std::function<void(int)> Callback)
{

}

void Function(int Number)
{

}
};

Но я хочу связать их напрямую, что-то вроде следующего.

// ...
Register(&Class::Function);
// ...

Я думаю, что в соответствии со стандартом C ++ 11 это должно поддерживаться. Тем не менее, в Visual Studio 11 я получаю эти ошибки компилятора.

ошибка C2440: «новая строка»: невозможно преобразовать из «int» в «класс *»

ошибка C2647: «. *»: невозможно разыменовать «void (__thiscall Class :: *) (int)» на «int»

12

Решение

Я думаю, что в соответствии со стандартом C ++ 11 это должно поддерживаться

Не совсем, потому что нестатическая функция-член имеет неявный первый параметр типа (cv-qualified) YourType*так что в этом случае это не совпадает void(int), Отсюда необходимость std::bind:

Register(std::bind(&Class::Function, PointerToSomeInstanceOfClass, _1));

Например

Class c;
using namespace std::placeholders; // for _1, _2 etc.
c.Register(std::bind(&Class::Function, &c, _1));

редактировать Вы упоминаете, что это должно быть вызвано с тем же Class пример. В этом случае вы можете использовать простую функцию, не являющуюся членом:

void (int n) foo
{
theClassInstance.Function(n);
}

затем

Class c;
c.Register(foo);
28

Другие решения

По словам Стефана Т. Лававея — «Избегайте использования bind (), …, используйте лямбды».
https://www.youtube.com/watch?v=zt7ThwVfap0&т = 32m20s

В этом случае:

Class()
{
Register([this](int n){ Function(n); });
}
18

Ты можешь использовать std::bind:

using namespace std::placeholders;  // For _1 in the bind call

// ...

Register(std::bind(&Class::Function, this, _1));
6

С std::function а также std::bind, вы можете относиться к различным функциям класса одинаково.

#include <iostream>
#include <functional>
#include <vector>
using namespace std;
using namespace std::placeholders;

class Foo
{
public:
void foo(const string &msg)
{
cout << msg << '\n';
}
};

class Bar
{
public:
void bar(const string &msg, const string &suffix)
{
cout << msg << suffix << '\n';
}
};

int main(int argc, char **argv)
{
Foo foo;
Bar bar;

vector<function<void (const string &msg)>> collection;
collection.push_back(bind(&Foo::foo, &foo, _1));
collection.push_back(bind(&Bar::bar, &bar, _1, "bar"));

for (auto f : collection) {
f("foo");
}

return 0;
}
1
По вопросам рекламы [email protected]