Question

Hi I am having an issue compiling the following code. I am using auto and std::bind to bind a callback function with arguments. However, after passing this callback function as a parameter, it has issues compiling. Do you see an issue with the function declarations below:

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

Please see below for the compile error log:

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) ===|

I supposed my question can be simplified as:

What does the function declaration for playSingleAd() need to be in order to compile the following successfully?:

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

Solution

When you bind a method to fully-supplied parameters, the resulting functor takes no arguments. In your code, playSingleAd takes a function pointer that takes as an argument, a function pointer whose arguments are to be supplied when called. Because you already bound the arguments to that function pointer, the arguments thereto cannot not be specified in the function signature.

Anyway, your code can be improved with the use of std::function. Moreover, the function will have to take the instance as an argument, as shown in the implementation of playSingleAd below:

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);
}
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top