C++11 styled callbacks?

后端 未结 2 1491
灰色年华
灰色年华 2020-12-04 10:51

I have a void function inside of a class. In old C++ i\'d make a function static taking the class name as a parameter and had my own class which took a static void function

相关标签:
2条回答
  • 2020-12-04 11:16

    For an example of passing in parameters to a C++ 11 callback using Lambda's and a vector, see http://ideone.com/tcBCeO or below:

    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);
    
        }
    }      
    
    0 讨论(0)
  • 2020-12-04 11:28

    Use std::function and lambdas (or std::bind()) to store callables:

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

    Result:

    BLAH!

    BIM!

    BOUM!

    BLAH!

    Compiles and run: http://ideone.com/T6wVp

    std::function can be used as any copyiable object, so feel free to store it somewhere as a callback, like in object's member. It also means that you can freely put it in standard containers, like std::vector< std::function< void () > > .

    Also note that equivalent boost::function and boost::bind have been available for years.

    0 讨论(0)
提交回复
热议问题