tr1::function对象作回调函数技术总结

  转载自:

    https://blog.csdn.net/this_capslock/article/details/38564719

 

之前写过一篇文章用于讨论如何让C++类内函数作成员函数,详情见http://blog.csdn.net/this_capslock/article/details/17001003

 

今天又发现了一个更好的方法,那就是使用C++的TR1中中包含一个function模板类和bind模板函数。使用它们可以实现类似函数指针的功能,但是比函数指针更加灵活。

 

对于tr1::function对象可以这么理解:它能接受任何可调用物,只要可调用物的的签名式兼容于需求端即可,比如函数指针,仿函数对象,成员函数指针,

 

例子如下:

 

  1.  
    #include <iostream>
  2.  
    #include <functional>//为了使用std::tr1::function
  3.  
    #include <string>
  4.  
    #include <sstream>
  5.  
    using namespace std;
  6.  
     
  7.  
    typedef tr1::function< int (const string&) > FUNC;
  8.  
    void InterfaceFunc( const string& a , const string& b , FUNC f )
  9.  
    {//测试用接口函数,将a+b得到的字符串转成整数并打印出来,f是回调函数
  10.  
    cout << f(a+b) << endl;
  11.  
    }

先自定义了一种function类型FUNC,它接受所有参数为const string&并且返回值是 int的签名对象。

 

函数InterfaceFunc第三个参数是一个FUNC对象,当作回调函数使用

 

下面是四种常见类型的“可调用物”:

 

  1.  
    int f1( const string& str )
  2.  
    {//正常函数
  3.  
    cout << "int f1( const string& str )" << endl;
  4.  
    stringstream ss;
  5.  
    ss << str;
  6.  
    int result;
  7.  
    ss >> result;
  8.  
    return result;
  9.  
    }
  10.  
     
  11.  
    class F2
  12.  
    {
  13.  
    public:
  14.  
    int operator()( const string& str )
  15.  
    {//仿函数
  16.  
    cout << "int F2::operator()( const string& str )" << endl;
  17.  
    stringstream ss;
  18.  
    ss << str;
  19.  
    int result;
  20.  
    ss >> result;
  21.  
    return result;
  22.  
    }
  23.  
    };
  24.  
     
  25.  
    class F3
  26.  
    {
  27.  
    public:
  28.  
    int f3( const string& str )
  29.  
    {//类内非静态成员函数
  30.  
    cout << "int F3::f3( const string& str )" << endl;
  31.  
    stringstream ss;
  32.  
    ss << str;
  33.  
    int result;
  34.  
    ss >> result;
  35.  
    return result;
  36.  
    }
  37.  
    };
  38.  
     
  39.  
    class F4
  40.  
    {
  41.  
    public:
  42.  
    static int f4( const string& str )
  43.  
    {//类内静态成员函数
  44.  
    cout << "static int F4::f4( const string& str )" << endl;
  45.  
    stringstream ss;
  46.  
    ss << str;
  47.  
    int result;
  48.  
    ss >> result;
  49.  
    return result;
  50.  
    }
  51.  
    };

这些函数都具有形如int (const string& )形式的签名式,所以都可以被FUNC对象接受。

 

具体调用的时候是这样的:

 

  1.  
    int main()
  2.  
    {
  3.  
    string a = "123";
  4.  
    string b = "456";
  5.  
     
  6.  
    //FUNC接受正常函数指针
  7.  
    InterfaceFunc( a , b , f1 );
  8.  
    cout << endl;
  9.  
     
  10.  
    //FUNC接受仿函数
  11.  
    InterfaceFunc( a , b , F2() );
  12.  
    cout << endl;
  13.  
     
  14.  
    //FUNC接受类内非静态成员函数
  15.  
    F3 f;
  16.  
    InterfaceFunc( a , b , tr1::bind( &F3::f3 , &f , tr1::placeholders::_1 ) );
  17.  
    cout << endl;
  18.  
     
  19.  
    //FUNC接受类内静态成员函数
  20.  
    InterfaceFunc( a , b , F4::f4 );
  21.  
    system("pause");
  22.  
    }

这里需要特别注意下,第三次让FUNC接受类内非静态成员函数时,使用了tr1::bind( &F3::f3 , &f , tr1::placeholders::_1 )这样东西作为参数,它的含义是:让&f作为F3::f3函数中的第1个参数,因为对于类内非静态成员函数,它有一个隐含的第一参数:this指针,因为成员函数是存储位置是在对象之外的,只根据F3::f3的地址无法得知具体对哪个对象操作,tr1::bind的作用正是告诉F3::f3,它隐含的this参数指向的是f这个已经定义好的对象,剩下的事情就和其它情况一样了。

 

 

测试结果一切正常,如下图:

posted @ 2018-08-05 10:43  博客园—哆啦A梦  阅读(248)  评论(0)    收藏  举报