各位肯定在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;
}