【问题标题】:Compile error with C++11 std::bind and auto for Callback function parameter使用 C++11 std::bind 和 auto 为回调函数参数编译错误
【发布时间】:2014-01-22 20:54:35
【问题描述】:

您好,我在编译以下代码时遇到问题。我正在使用 auto 和 std::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);
}

【问题讨论】:

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


    【解决方案1】:

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

    无论如何,使用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);
    }
    

    【讨论】:

    • 感谢您的回复。我不知道!啊,我更新了我的代码,但它似乎仍然无法编译。你觉得我的函数声明有什么问题吗?
    • 它指出问题出在“playSingleAd(123, cb);”线上- 错误:没有匹配函数调用“VmapPlayer::playSingleAd()....”
    • 这是因为“cb”的数据类型为“auto”吗? playSingleAd() 的函数声明有问题吗?
    • @user1456962 这是整个错误消息吗?我只是想确保我能看到你所看到的一切。另外,您可以将错误复制粘贴到您的问题中吗?
    • 我将错误复制粘贴到问题的底部。谢谢
    猜你喜欢
    • 2015-09-12
    • 2016-11-13
    • 2014-04-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-09-01
    • 2021-11-23
    相关资源
    最近更新 更多