【问题标题】:How to pass argument to std::bind to a function?如何将参数传递给 std::bind 到函数?
【发布时间】:2019-04-20 02:56:13
【问题描述】:

我有以下使用 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));

Constants::MY_EVENT 等只是 const char* 。

唯一的区别是被调用的函数,以及用作事件名称的字符串常量。我怎样才能把它封装成一个函数?我在下面尝试了 John Zwinck 的解决方案,但由于某种原因我无法编译它,因为编译器会抱怨:

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

【问题讨论】:

    标签: c++ c++11


    【解决方案1】:

    为简单起见,为指向MyClass 中具有适当签名的任何成员函数的指针创建一个typedef:

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

    【讨论】:

    • 但这不会使其不可重用,因为我只能使用已在 typedef 中定义的函数吗?如果我想在其他类中传递其他函数怎么办?
    • @KaizerSozay:那个 typedef 被称为 MyMemberFn 并且不引用任何特定的成员函数,也就是说它与 MyClass 中的任何成员函数兼容,它采用 int (或任何单一的参数是你有的),并返回void(或任何你的实际函数返回,只要它们在签名上都一样)。
    • 有没有我可以阅读的文档来更好地理解 typedef 的这种特定用法?语法对我来说似乎很奇怪。
    • 它无法识别我的类名,即使我已将 typedef 语句直接放在我的类定义之上。它说“使用未声明的标识符'MyClass'。
    • 如果您从 typedef 中删除 'MyClass',则会出现错误:Noviable conversion from '__bind &>' 到 'const std::function'
    【解决方案2】:

    您真正要找的是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。两者都应该有帮助。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-09-10
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多