boost 函数--回调--c 回调的自定义

4 篇文章 1 订阅

各位肯定在ros中见过ref bind 等。

#include <boost/ref.hpp>     
#include <iostream>   
#include <vector>
#include <algorithm>
#include <assert.h>
#include <set>


using namespace std;
using namespace boost;

int main()
{
    //for_each
    struct square
    {
        typedef void result_type;
        void operator() (int& x)
        {
            x = x * x; 
            cout << x << endl;
        }

    };
    vector<int> v = { 1,2,3,4,5 };
    for_each(v.begin(),v.end(),square());


    //reference_wrapper 被包装对象的别名
    int x = 10;
    boost::reference_wrapper<int>   rw1(x);
    assert(rw1 == x);
    (int&)rw1 = 100;
    assert(x == 100);
    cout << rw1 << endl;

    boost::reference_wrapper<int> rw2(rw1);
    assert(rw2.get() == 100);

    string str;
    string str2("limao");
    boost::reference_wrapper<string> rws(str);
    boost::reference_wrapper<string> rws2(str2);

    *rws.get_pointer() = "test_reference";
    std::cout << rws2.get().size() << "__" << rws2.get().c_str() << endl;

    //reference_wrapper<> 太长啦,ref 库提供了两个便捷的工厂函数
    //reference_wrapper<T>     ref(T& t);
    //reference_wrapper<T const> cref(T const& t);
    //特点:通过参数类型自动推到构造,不需要<>指定啦
    double w = 2.7128;
    auto rwx = boost::cref(w);
    std::cout << typeid(rwx).name() << endl;
    //在c++中,typeid用于返回指针或引用所指对象的实际类型。属于操作符,不是函数

    string strr;
    auto rwstr = boost::ref(str);
    cout << typeid(rwstr).name() << " " << endl;

    //支持拷贝,可以直接用在需要拷贝语意的函数参数中
    double xx = 2.0;
    cout << std::sqrt((long)boost::ref(x)) << endl;

    //包装操作--1.判断--2.解包装(判断真实类型)
    vector<int> vv(10, 2);
    auto rwvv = boost::cref(vv);
    assert(is_reference_wrapper<decltype(rwvv)>::value);
    assert(!is_reference_wrapper<decltype(vv)>::value);
    //以反映其具有获取表达式的“声明类型”(Declared Type)的功能,而不求值

    string strvv;
    auto rwstrvv = boost::ref(strvv);
    cout << typeid(unwrap_reference<decltype(rwvv)>::type).name() << endl;
    cout << typeid(unwrap_reference<decltype(rwstr)>::type).name() << endl;

    //解开包装更简洁用法,unwrap_ref(),返回被包装对象的引用。
    set<int> sint;
    auto rwsint = boost::ref(sint);
    unwrap_ref(rwsint).insert(12); //直接解开包装

    string str_unwrap("mao22");
    auto rwstrunwrap = boost::cref(str_unwrap);
    cout << boost::unwrap_ref(rwstrunwrap).c_str() << endl;
    cout << boost::unwrap_ref(str_unwrap).c_str() << endl;

    return 0;
}

bind

#include <boost/bind.hpp>     
#include <iostream>   
#include <vector>
#include <algorithm>
#include <assert.h>
#include <set>
#include<functional>   //greater<> less<> plus() modulus()

int add(int a, int b)
{
    int sum = a + b ;
    return sum; 

}
using namespace std;
using namespace boost;

class demo
{
private:
    int a;
    int b;
public:
    demo(int da, int db, int dc = 0) :a(da), b(db) {}
    demo()
    {
        a = 0;
        b = 0;
        c = 0;
    }
    int fundemo(int f ) 
    {
        int s = a + b + f;
        return s;
    }
    void print()
    {
        std::cout << "__" << a << " __ " << b << endl;
    }
    int c;
};

//自定义函数对象,(没有result_type类型定义)
struct funobj
{
    int operator()(int fa, int fb)
    {
        return fa + fb;
    }

};

int main()
{
    //普通函数,最多可绑定9个参数,且对被绑定对象的要求很低_1 _2 .... _9
    int aa = 1, bb = 2;
    std::cout << "  1  " << bind(add, aa, bb)() << std::endl;
    std::cout << "  2  " << bind(add, _2, _1)(bb, aa) << std::endl;    // 等价于add(aa,bb)

    int cc = 3;
    std::cout << bind(add, _1, 4)(cc) << std::endl;

    //类的成员函数,成员函数指针无法调用operator(),必须绑定一个对象或者指针,然后调用this指针来调用。
    //需要bind提供一个占位符,用来提供一个类的实例、引用、指针,最多8个参数
    //如class demo
    demo a(1,5), &ra = a;
    demo *p = &a;
    std::cout << "  3  " <<  bind(&demo::fundemo, a, _1)(100) << std::endl;  //第二个参数应该是重载
    std::cout << "  4  " <<  bind(&demo::fundemo, ra, _1)(200) << std::endl;
    std::cout << "  5  " <<  bind(&demo::fundemo, p, _1)(300) << std::endl;

    vector<demo> vv(10);
    for_each(vv.begin(), vv.end(), bind(&demo::print, _1));
    //绑定函数对象 bind<result_type>(functor,...)
    cout << "  6  " << bind(std::greater<int>(), _1, 10)(20) << endl;
    cout << "  7  " << bind(std::plus<int>(), _1, _2)(11,22) << endl;
    cout << "  8  " << bind(std::modulus<int>(), _1, 3)(20) << endl;

    //绑定函数对象,没有result_type 所以必须在模板参数里指明bind的返回值类型
    cout << "  9  " << bind<int>(funobj(), _1, _2)(20,40) << endl;

    //bind 以上采用的都是参数值传递(拷贝参数)的方式,如果参数很大则代价较高,那么怎么引用传值呢
    int refx = 100;
    cout << "  10  " << boost::bind(add, boost::cref(refx), boost::ref(refx))() << endl;
    funobj fo; //使用默认的构造函数,所以直接fo即可
    cout << "  11  " << boost::bind<int>(boost::ref(fo),_1,_2)(10,20) << endl;
    return 0;
}

function 函数对象

#include <boost/bind.hpp>  
#include <boost/function.hpp>
#include <iostream>   
#include <vector>
#include <algorithm>
#include <assert.h>
#include <set>
#include<functional>   //greater<> less<> plus() modulus()

using  std::cout;
using std::endl;
using namespace boost;

int add(int a, int b)
{
    int sum = a + b ;
    return sum; 
    }

struct demo_class
{
    int add(int a, int b)
    {
        return a + b;
    }
    int operator()(int x)const
    {
        return x*x;
    }

};

int main()
{
    //function<int()> func; 函数容器,可想象成一个泛化的函数指针
    // function 只需要一个模板参数,返回类型为 int,无惨
    //No.1
    //fuction<int(int a,int b,int c)>
    //function<int(int, int, int)>

    //No.2
    //int f(int a ,int b){   };
    //function<decltype(f)> func;
    function<int(int, int)> func;
    assert(!func);             //此时的function不持有对象
    func = add;               //func存储函数f
    assert(func.contains(&add));

    if (func)
    {
        cout << func(11, 22) << std::endl;

    }
    func = 0;

    assert(func.empty());

    //存储成员函数的方法:

    demo_class dc;
    function<int(int, int)> func2;
    func2 = bind(&demo_class::add, &dc, _1, _2);
    cout << func2(13, 23);

    //使用ref
    //function使用拷贝方式保存参数,当参数很大时,可以向ref求助
    function<int(int)> func3;
    func3 = cref(dc);   //使用cref()包装对象的引用
    cout << func3(10) << endl;

    return 0;
}

function 类内外回调

#include <boost/bind.hpp>  
#include <boost/function.hpp>
#include <iostream>   
#include <vector>
#include <algorithm>
#include <assert.h>
#include <set>
#include<functional>   //greater<> less<> plus() modulus()

using  std::cout;
using std::endl;
using namespace boost;

class demo
{
private:
    typedef function<void(int)> func_t;
    func_t funclass;
    int n;
public:
    demo(int i) :n(i) {};
    //定义回调函数
    template<typename callback>
    void accept(callback f)
    {
        funclass = f;
    }
    //定义成员函数run()用于调用回调函数
    void run()
    {
        funclass(n);
    }

};
//定义用于回调的函数(类外普通函数)
void call_back_func(int i)
{
    cout << "call back func" << endl;
    cout << i * 2 << endl;
};
//回调 带状态的函数对象
class call_back_obj
{
private:
    int x;
public:
    call_back_obj(int f) : x(f) {};
    void operator()(int i)
    {
        cout << "call back obj" << endl;
        cout << i * x++ << endl;
    }

};

//function 搭配bind 库,把bind 表达式作为回调函数,可以接受类成员函数
class call_back_factory
{
public:
    void call_back_f_func1(int i)
    {
        cout << "call back facotry func1" << endl;
        cout << i * 2 << endl;
    }
    void call_back_f_func2(int i, int j)
    {
        cout << "call back factory func2" << endl;
        cout << i*j * 2 << endl;
    }

};
int main()
{
    //用于回调,调用普通函数
    demo de(10);
    de.accept(call_back_func);
    de.run();

    //用于回调  带状态的类成员函数
    demo dd(20);
    call_back_obj cbo(2);
    dd.accept(ref(cbo));
    dd.run();
    dd.run();

    //用于回调,bind 搭配function 用法
    demo db(14);
    call_back_factory cbf;
    db.accept(bind(&call_back_factory::call_back_f_func1, cbf, _1));
    db.run();

    db.accept(bind(&call_back_factory::call_back_f_func2, cbf, _1, 5));
    db.run();

    return 0;
}
  • 常规c 怎么定义回调呢?
#include <stdio.h>

typedef int(*callbackfun)(char *p);
int Afun(char *p)
{
    printf("Afun--%s\n",p);
    return 0;
}

int Bfun(char *p)
{
    printf("Bfun--%s\n", p);
    return 0;
}
//way1: 通过命名方式
int call(callbackfun pcb, char*p)
{
    printf(" ----- way1------\n ");
    pcb(p);
    return 0;
}
//way2:直接通过方法指针
int call2(char* p, int(*ptr)(char* p))
{
    printf("\n-----way2------\n");
    (*ptr)(p);
    return 0;
}

int main()
{
    char *p = "hello world !";

    call(Afun,p);
    call2(p, Afun);

    return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值