一些简单的例子:
使容器中的元素都减去5
std::for_each(vec.begin(), vec.end(), _1 -= 5);
计算容器中元素所有和
int nSum = 0;
std::for_each(vec.begin(), vec.end(), nSum += _1);
基础:
1. 创建一个无参的lambda表达式:
boost::function<int()> func = boost::lambda::constant(a + 5);
2. 定义lambda表达式常量与变量 可以lambda表达式中进行运算
常量:boost::lambda::constant_type<T>::type var1;
变量:boost::lambda::var_type<T>::type var2;
如: using boost::lambda::constant_type;
using boost::lambda::var_type;
constant_type<T>::type var1(boost::constant(value));
var_type<T>::type var2(boost::lambda::var(value));
注意以上的定义式 常量需要使用boost::constant包装 变量需要使用boost::lambda::var包装
3. bind 绑定重载函数 bind不能直接绑定重载函数,由于不能找到正确的函数地址 如果想绑定重载函数,需要手动的赋值函数地址给bind表达式 如:
void foo(int);
void foo(float);
bind(&foo, _1)(i) //error 不能正确的找到函数地址 存在二义性
解决方案:
void (*pf1)(int) = &foo; //定义函数指针变量
bind(pf1, _1)(i) //ok 将调用void foo(int) 函数
关于bind函数的其他注意事项:是否修改本身的问题(以及性能)
class A
{
void set_i(int k);
};
A a;
int k;
bind(&A::set_i, a, _1)(k); //a被复制 如果修改a的话 只是修改了副本 类似于函数的传值调用
bind(&A::set_i, &a, _1)(k);//a的指针被复制 如果修改a的话 将修改a自身 类似于函数的传指针调用
bind(&A::set_i, boost::ref(a), _1)(k);//a被传引用 如果修改a的话 将修改a自身 类似于函数的传引用调用
bind(&A::set_i, _1, 1)(k);//a被传引用 如果修改a的话 将修改a自身 类似于函数的传引用调用
除了第一个bind外 其他的都是穿类似引用的方式调用成员函数 第一个bind性能没有其他三个的优
4. lambda的控制结构
if_then(condition, then_part);
if_then_else(condition, the_part, else_pari);
if_then_else_return(condition, then_part, else_part);
while_loop(condition, body);
while_loop(condition);
do_while_loop(condition, body);
do_while_loop(condition);
for_loop(init, condition, increment, body);
for_loop(init, condition, increment);
除了if_then_else_return有返回类型 其他的都返回void
对二维数组每个元素进行+1
int a[5][10];
int i;
std::for_each(a, a+5, for_loop(var(i) = 0, var(i) < 10, ++var(i), _1[var(i)] += 1));
5. 嵌套的stl算法 计算二维数组中所有的和
#include <boost/lambda/algorithm.hpp>
using boost::lambda::ll;
int a[100][200];
int nSum = 0;
std::for_each(a, a+100, bind(ll::for_each(), _1, _1 + 200, protect(nSum += _1));
命名空间中还有很多类似ll::for_each的类似stl函数, 大家可以尽情的发挥想象力
以上更为标准的写法如下:
std::for_each(a.begin(), a.end(), bind(ll::for_each(), bind(call_begin(), _1), bind(call_end(), _1), protect(nSum += _1)));
6. boost::bind 与boost::lambda::bind的区别
template <typename FUN>
int nested(FUN fun)
{
int k = 10;
bind(fun, _1)(k);
}
int bar(int a, int b)
{
return a + b;
}
nested(boost::lambda::bind(bar, 1, _1)) => bar(1, x)(x); 最终编译不过 可以使用unlambda函数进行解决
nested(boost::bind(bar, 1, _1)) => bar(1, x) 符合预期值 顺利通过
boost::bind 有最多9个占位符
boost::lambda::bind 有最多3个占位符
7. 构造与析构
constructor<T>()(arg_list);
destructor()(a);
destructor()(pa);
new_ptr<T>()(arg_list)
new_array<T>()(sz);
delete_ptr()(p);
delete_array()(p);
类型转换函数
ll_static_cast
ll_dynamic_cast
ll_const_cast
ll_reinterpret_cast
ll_sizeof
ll_typeid