关于boost中lambda表达式的学习

来源:互联网 发布:淘宝茶叶有多少人竞争 编辑:程序博客网 时间:2024/05/17 01:04

一些简单的例子:

使容器中的元素都减去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




0 0
原创粉丝点击