c++ - 回调函数参数的 C++11 std::bind 和 auto 编译错误

标签 c++ c++11 callback auto stdbind

您好,我在编译以下代码时遇到问题。我正在使用 auto 和 std::bind 将回调函数与参数绑定(bind)。但是,将此回调函数作为参数传递后,编译出现问题。您是否发现以下函数声明存在问题:

#include <iostream>
#include <functional>
using namespace std;

class VmapPlayer
{
    public:
        void startPlayback();
        void playAdBreak(int adBreak, void (VmapPlayer::*callback)());
        void playSingleAd(int ad, void (VmapPlayer::*callback)(int adBreak, void (VmapPlayer::*cb)()));
};

void VmapPlayer::playSingleAd(int ad, void (VmapPlayer::*callback)(int adBreak, void (VmapPlayer::*cb)()))
{
    cout << "i am here" << endl;

    // OPTION #1 I would like to call this function
    //(this->*callback)(adBreak, cb);

    // OPTION #2 I would like this call this function without the params:
    //(this->*callback)();
}

void VmapPlayer::playAdBreak(int adBreak, void (VmapPlayer::*callback)())
{
    auto cb = std::bind(&VmapPlayer::playAdBreak, adBreak, callback);
    playSingleAd(123, cb);
}

void VmapPlayer::startPlayback()
{
    playAdBreak(456, &VmapPlayer::startPlayback);
}

int main()
{
    VmapPlayer p;
    p.startPlayback();

    return 0;
}

编译错误日志见下:

main.cpp||In member function 'void VmapPlayer::playAdBreak(int, void (VmapPlayer::*)())':|
main.cpp|28|error: no matching function for call to 'VmapPlayer::playSingleAd(int, std::_Bind<std::_Mem_fn<void (VmapPlayer::*)(int, void (VmapPlayer::*)())>(int, void (VmapPlayer::*)())>&)'|
main.cpp|28|note: candidate is:|
main.cpp|14|note: void VmapPlayer::playSingleAd(int, void (VmapPlayer::*)(int, void (VmapPlayer::*)()))|
main.cpp|14|note:   no known conversion for argument 2 from 'std::_Bind<std::_Mem_fn<void (VmapPlayer::*)(int, void (VmapPlayer::*)())>(int, void (VmapPlayer::*)())>' to 'void (VmapPlayer::*)(int, void (VmapPlayer::*)())'|
||=== Build finished: 1 errors, 0 warnings (0 minutes, 0 seconds) ===|

我想我的问题可以简化为:

playSingleAd() 的函数声明需要怎样才能成功编译以下内容?

void VmapPlayer::playAdBreak(int adBreak, void (VmapPlayer::*callback)())
{
    auto cb = std::bind(&VmapPlayer::playAdBreak, adBreak, callback);
    playSingleAd(123, cb);
}

最佳答案

当您将方法绑定(bind)到完全提供的参数时,生成的仿函数不接受任何参数。在您的代码中,playSingleAd 采用一个函数指针作为参数,该函数指针的参数将在调用时提供。因为您已经将参数绑定(bind)到该函数指针,所以不能在函数签名中指定其参数。

无论如何,您的代码可以通过使用 std::function 来改进。此外,该函数必须将实例作为参数,如下面的 playSingleAd 实现所示:

class VmapPlayer
{
public:
    void startPlayback();
    void playAdBreak(int adBreak, void (VmapPlayer::*callback)());
    void playSingleAd(int ad, std::function<void (VmapPlayer&)>);
};

void VmapPlayer::playSingleAd(int, std::function<void (VmapPlayer&)> callback)
{
    cout << "i am here" << endl;
    callback(*this);
}

void VmapPlayer::playAdBreak(int adBreak, void (VmapPlayer::*callback)())
{
    using namespace std::placeholders;
    auto cb = std::bind(&VmapPlayer::playAdBreak, _1, adBreak, callback);
    playSingleAd(123, cb);
}

关于c++ - 回调函数参数的 C++11 std::bind 和 auto 编译错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21293787/

相关文章:

c++ - 成员变量的临时可变性

c++ - Consexpr 与宏

为参数 `type name' 指定的 C 函数指针错误存储类

C++ 输出运算符重载

c++ - 重载基类函数

C++11 decltype : How to declare the type that a pointer points to?

ruby-on-rails - ruby on has_many :through上的after_remove,after_add回调

javascript - 如何在 Model.find( obj , callback) 上传播回调 promise 值?

c++ - `noexcept` getters 和 setters 说明符

c++ - 在 C++ 中缩写 for 循环