Как передать аргумент в std :: bind функции? - PullRequest
0 голосов
/ 20 апреля 2019

У меня есть следующий код, который использовал std :: bind:

 EventListenerCustom* _createNewObjectlistener = 
eventDispatcher->addCustomEventListener(Constants::MY_EVENT, 
std::bind(&MyClass::MyFunction, this, std::placeholders::_1));

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

  • Как бы я передал MyClass :: MyFunction в качестве аргумента функции?
  • Как будут выглядеть сигнатура и параметры функции?

Я полагаю, что функция будет выглядеть примерно так:

EventListenerCustom* MyFunc(<What Goes Here> functionToBeBound,<What goes here> object,std::string EVENT){
    EventListenerCustom* eventListener = eventDispatcher->addCustomEventListener(EVENT, std::bind(functionToBeBound, object, std::placeholders::_1));
    return eventListener;
}

Как должна выглядеть функция? И как я это называю? Как будет выглядеть код вызова?

РЕДАКТИРОВАТЬ: Конкретные детали:

У меня есть много объектов слушателей, которые созданы одинаковыми способами:

auto eventDispatcher = _dragNode->getEventDispatcher();

_createNewObjectlistener = eventDispatcher->addCustomEventListener(Constants::MY_EVENT, std::bind(&MyClass::myOtherFunction, this, std::placeholders::_1));

_moveNewObjectlistener = eventDispatcher->addCustomEventListener(Constants::MY_EVENT2 std::bind(&MyClass::myFunction, this, std::placeholders::_1));

Константы :: MY_EVENT и т. Д. Являются просто константными символами *.

Единственным отличием является вызываемая функция и строковая константа, используемая в качестве имени события. Как я могу заключить это в функцию? Ниже я попробовал решение Джона Цвинка, но по какой-то причине не могу его скомпилировать, потому что компилятор жалуется:

: No viable conversion from '__bind<void (*&)(cocos2d::EventCustom *), MyNameSpace::MyClass *, const std::__1::placeholders::__ph<1> &>' to 'const std::function<void (EventCustom *)>'

Ответы [ 2 ]

1 голос
/ 20 апреля 2019

Чтобы упростить задачу, создайте typedef для указателя на любую функцию-член в MyClass, которая имеет соответствующую подпись:

typedef void (MyClass::*MyMemberFn)(int); // replace int and void as needed

Тогда:

EventListenerCustom* MyFunc(MyMemberFn functionToBeBound, MyClass* object, std::string EVENT){
    return eventDispatcher->addCustomEventListener(EVENT, std::bind(functionToBeBound, object, std::placeholders::_1));
}
0 голосов
/ 23 апреля 2019

То, что вы действительно ищете, это std::function.Документация для этого здесь: https://en.cppreference.com/w/cpp/utility/functional/function

Их пример действительно хорош в объяснении, как он используется, но для вашего случая (или связанного с ним) попробуйте это:

std::function<void(int)> func1 = std::bind(MyClass::MyFunction, this, std::placeholders::_1));

Что это будет делать, это создать объект, который можно вызвать, и первый аргумент будет перенаправлен на первый аргумент функции-члена, оба из которых должны иметь тип int, и он ничего не возвращает.На самом деле вам не нужен оператор адреса для имени функции.

Крутая часть в том, что объект, возвращаемый std::bind, может быть передан в конструктор std::function, и вся его информация сохраняется,Поэтому, когда вам нужен конкретный тип, который можно скопировать, и все эти интересные вещи (передаваемые в функцию НЕ по ссылке, например), тогда используйте std::function, поскольку он будет выполнять работу, если он не пытается копировать неКопируемый тип или что-то.std::function также можно инициализировать указателем на функцию.Обычно это просто «лучше», чем указатели функций для C ++, особенно в сочетании с std::bind для обработки классов.

Я мог бы написать больше примеров, но ознакомьтесь с приведенной выше ссылкой и ознакомьтесь с std::bindтот же сайт.Оба должны помочь.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...