Передача указателя на функцию обратного вызова функции в другом классе - PullRequest
0 голосов
/ 29 апреля 2020

Я знаю, что такие вопросы задавались, но ни один из ответов не помог мне. Несмотря на то, что в прошлом я по мере необходимости кодировал немного C ++, я не очень хорошо разбираюсь. Сегодня я застрял, пытаясь передать функцию обратного вызова функции в другом классе. Ниже приведен краткий пример:

#include "stdafx.h"
#include <functional>

class A
{
private:
    int _someMemberVar = 7;

public:
    void SomeFunction(std::function<void(int)> func)
    {
        func(_someMemberVar);
    }
};

class B
{
public:
    void DoSomeWork()
    {
        A a;

        // error C2275: 'std::function<void (int)>' : illegal use of this type as an expression
        a.SomeFunction(std::function<void(int)> &B::MyCallback);
    }

    void MyCallback(int i)
    {
        printf("parameter is %d\r\n", i);
    }
};

int _tmain(int argc, _TCHAR* argv[])
{
    B b;
    b.DoSomeWork();

    return 0;
}

Я попробовал пример кода с этой страницы std :: function документации , но он не компилируется. У меня были похожие проблемы с другими примерами, которые я нашел, например, в диссертации здесь . Я использую Visual Studio 2013.

Поиск различных ошибок компилятора не помог мне разобраться с этим, и я чувствую разочарование и растерянность. Единственное, что я точно знаю, это то, что мы C# программисты уверены, что они избалованы. Любая помощь очень ценится.


Редактировать: Большое спасибо за помощь всем. Все ответы предоставили работающее решение, и если бы я мог зеленый, проверьте их все, я бы сделал. Я пошел с ответом, опубликованным super, потому что он имел больше всего объяснений и, кажется, ближе всего к тому, что я портирую. Еще раз спасибо всем!

Ответы [ 3 ]

2 голосов
/ 29 апреля 2020

Помимо пропущенных скобок вокруг &B::MyCallback (опечатка?), Основная проблема заключается в том, что функция-член и обычная функция - это не одно и то же.

Функция-член действует на объект, в то время как функции нет, поэтому указатель на функцию-член не может быть просто преобразован в обычный указатель функции.

Самое простое решение в вашем случае - передать лямбду, которая захватывает this.

a.SomeFunction([&](int i){ MyCallback(i); });

Лямбда будет захватывать текущий объект и пересылать i в качестве параметра функции-члену.

2 голосов
/ 29 апреля 2020

Вот еще один способ сделать то же самое. Предполагая, что вы не хотите изменять метод на метод stati c и хотите вызвать метод MyCallback для this

using namespace std::placeholders;

    std::function<void(int)> func = std::bind(&B::MyCallback, this, _1);
    a.SomeFunction(func);
2 голосов
/ 29 апреля 2020

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

a.SomeFunction([this] (int const i) { MyCallback(i); });
...