要点:
1 c++是面向对象的语言,尽量把所以一切东西看成对象,包括数据类型,函数,表达式,所以把这些东西转换为对象时非常关键的,
boost基本上就是把什么都看做是对象来处理,这样把一般函数或表达式转化为函数对象很重要,同前一次说的bind,和这一次要学习
的lambda,本质的作用就是把函数或表达式转换为函数对象;lambda可以把表达式转换为函数对象,避免了程序中写很多仿函数,程序
中太多的仿函数定义也是比较麻烦的,因为很多仿函数仅仅是用一次;lambda体现出优势了;
2 以例子开始:
(std::cout << _1 << " " << _3 << " " << _2 << "!\n")("Hello","friend","my");
上面就是一个lambda表达式,本质上是函数对象;这里也用了占位符_1...;这些占位符的本身也是函数对象;看下面的:
boost::function<void(int,int,int)> f= std::cout << _1 << "*" << _2 << "+" << _3 << "=" <<_1*_2+_3 << "\n";
f(1,2,3);
这里更加明显体现了lambda是函数对象的本质了;
3 占位符最多有9个,但是如果9个都用完了怎么办?
既然占位符也是函数对象,主要多出来的用函数对象来代替即可,所起的作用是一样的;
这里转换为函数对象的方法也是bind,但是不是上次学的bind,而是boost/lambda/bind.hpp里面的bind,用法和上次学的bind基本一样
例子:
typedef std::map<int,std::string> type;
type keys_and_values;
。。。
std::for_each( keys_and_values.begin(),keys_and_values.end(), std::cout << constant("key=") <<bind(&type::value_type::first,_1) << ", value=" << bind(&type::value_type::second,_1) << '\n');
上面的constant, 它创建一个无参函数对象;
4 使用ptr_fun, mem_fun, 或 mem_fun_ref 时,想想是否可以用lambda来代替
5 使用lambda来简化代码编写
int main() {
using namespace boost::lambda;
std::vector<int> vec(3);vec[0]=1; vec[1]=2; vec[2]=3;
std::for_each(vec.begin(),vec.end(),_1+=10);//么个元素加10
std::for_each(vec.begin(),vec.end(),_1-=10);
std::for_each(vec.begin(),vec.end(),_1*=3);
std::for_each(vec.begin(),vec.end(),_1/=2);
std::for_each(vec.begin(),vec.end(),_1%=3);}
看看多么简洁;
6 当bind绑定函数对象时,要指定返回类型
std::transform(vec.begin(),vec.end(),vec.begin(), bind<int>(var(ap),_1));7 如果函数对象从 unary_function/binary_function继承,就不需要显示指定返回类型了,因为这两个里面都有 result_type的定义
从这连个东西继承也是函数对象的标准写法,现在看到标准写法的重要了吧,因为更能与标准兼容
8 lambda表达式的控制
if_then(_1<5,std::cout << constant("Less than 5")))(3);
(if_(_1==0) [std::cout << constant("Nothing")].else_[std::cout << _1])(make_const(0));
int val1=1; int val2=4; (while_loop(_1<_2, (++_1,std::cout << constant("Inc...\n"))))(val1,val2);程序很难读,难以理解,不建议使用。