38

クラス内にvoid関数があります。古いC++では、クラス名をパラメーターとして使用して関数を静的にし、静的なvoid関数+void*を使用して簡単に呼び出すことができる独自のクラスを作成していました。

しかし、それは古い学校を感じます。また、テンプレート化されていないため、もっと多くのことができるように感じます。myclassVar.voidReturnVoidParamFuncへのコールバックを作成するより現代的な方法は何ですか

4

2 に答える 2

68

呼び出し可能値を格納するためstd::functionのラムダ(またはstd::bind()を使用します。

#include <functional>
#include <iostream>


class Test
{
public:
      void blah() { std::cout << "BLAH!" << std::endl; }
};

class Bim
{
public:
      void operator()(){ std::cout << "BIM!" << std::endl; }
};

void boum() { std::cout << "BOUM!" << std::endl; }


int main()
{
    // store the member function of an object:
    Test test;  
    std::function< void() > callback = std::bind( &Test::blah, test );
    callback();

    // store a callable object (by copy)
    callback = Bim{};
    callback();

    // store the address of a static function
    callback = &boum;
    callback();

    // store a copy of a lambda (that is a callable object)
    callback = [&]{ test.blah(); }; // often clearer -and not more expensive- than std::bind()
    callback();
}      

結果:

ブラ!

BIM!

BOUM!

ブラ!

コンパイルして実行します:http://ideone.com/T6wVp

std::functionコピー可能なオブジェクトとして使用できるため、オブジェクトのメンバーのように、コールバックとしてどこかに自由に保存してください。また、のような標準的なコンテナに自由に入れることができることも意味しますstd::vector< std::function< void () > >

また、同等のboost::functionとboost::bindが何年も利用可能であることに注意してください。

于 2012-09-09T11:45:27.970 に答える
8

Lambdaとベクターを使用してC++11コールバックにパラメーターを渡す例については、 http: //ideone.com/tcBCeO以下を参照してください。

class Test
{
public:
      Test (int testType) : m_testType(testType) {};
      void blah() { std::cout << "BLAH! " << m_testType << std::endl; }
      void blahWithParmeter(std::string p) { std::cout << "BLAH1! Parameter=" << p << std::endl; }
      void blahWithParmeter2(std::string p) { std::cout << "BLAH2! Parameter=" << p << std::endl; }

      private:
         int m_testType;

};

class Bim
{
public:
      void operator()(){ std::cout << "BIM!" << std::endl; }
};

void boum() { std::cout << "BOUM!" << std::endl; }


int main()
{
    // store the member function of an object:
    Test test(7);  
    //std::function< void() > callback = std::bind( &Test::blah, test );
    std::function< void() > callback = std::bind( &Test::blah, test );
    callback();

    // store a callable object (by copy)
    callback = Bim{};
    callback();

    // store the address of a static function
    callback = &boum;
    callback();

    // store a copy of a lambda (that is a callable object)
    callback = [&]{ test.blah(); }; // might be clearer than calling std::bind()
    callback();

    // example of callback with parameter using a vector
    typedef std::function<void(std::string&)> TstringCallback;

    std::vector <TstringCallback> callbackListStringParms;
    callbackListStringParms.push_back( [&] (const std::string& tag) {     test.blahWithParmeter(tag); }); 
    callbackListStringParms.push_back( [&] (const std::string& tag) { test.blahWithParmeter2(tag); }); 

    std::string parm1 = "parm1";
    std::string parm2 = "parm2";
    int i = 0;
    for (auto cb : callbackListStringParms ) 
    {
        ++i;
        if (i == 1)
            cb(parm1);
        else
            cb(parm2);

    }
}      
于 2013-05-15T02:31:28.587 に答える