0

こんにちは、次のコードのコンパイルで問題が発生しています。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);
}
4

1 に答える 1

1

メソッドを完全に指定されたパラメーターにバインドすると、結果のファンクターは引数を取りません。コードでplaySingleAdは、引数として取る関数ポインターを受け取ります。これは、呼び出されたときに引数が提供される関数ポインターです。既にその関数ポインターに引数をバインドしているため、その関数ポインターへの引数を関数シグネチャで指定することはできません。

とにかく、コードは を使用して改善できますstd::functionplaySingleAdさらに、以下の実装に示すように、関数は引数としてインスタンスを取る必要があります。

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);
}
于 2014-01-22T21:00:43.323 に答える