C++11: nullptr、默认函数的控制、lambda函数(二)

2014-11-24 07:22:16 · 作者: · 浏览: 1
,lambda底层实现和仿函数差不多,和仿函数一样它们都有初始状态,仿函数通过对象实例化时初始化数据成员获得初始态,lambda通过获取父作用域中的变变量作为初始态。但是lambda正是受限于只能接收父作用域的变量,因此不像仿函数那样可以跨域使用,但是lambda函数本来的设计目的就是局部函数。

对于按值传递的捕捉列表,其传递的值在lambda函数定义的时候就已经决定了,而按传值引用的捕捉列表其传递的值跟随绑定对象改变而改变,如下:

#include 
        
         
using namespace std;

int main() {
    int j = 12;
    auto by_val_lambda = [=] { return j + 1;};
    auto by_ref_lambda = [&] { return j + 1;};
    cout << "by_val_lambda: " << by_val_lambda() << endl;//13
    cout << "by_ref_lambda: " << by_ref_lambda() << endl;//13

    j++;
    cout << "by_val_lambda: " << by_val_lambda() << endl;//13
    cout << "by_ref_lambda: " << by_ref_lambda() << endl;//14
}
        
C++11允许lambda表达式向函数指针转换,但前提是lambda没有捕捉任何变量,且函数指针的函数原型和lambda相同,如下:

int main() {
    int girls = 3, boys = 4;
    auto totalChild = [](int x, int y)->int{ return x + y; };
    typedef int (*allChild)(int x, int y);
    typedef int (*oneChild)(int x);
    allChild p;
    p = totalChild;//lambda表达式赋值给函数指针
    oneChild q;
    q = totalChild;     // 编译失败,参数必须一致
    decltype(totalChild) allPeople = totalChild;    // 需通过decltype获得lambdas的类型
    decltype(totalChild) totalPeople = p;           // 编译失败,指针无法转换为lambda
    return 0;
}
lambda默认是const,可以通过mutable去掉const,如下:

int main(){
    int val;
    // 编译失败, 在const的lambda中修改常量
    auto const_val_lambda = [=]() { val = 3;};

    // 非const的lambda,可以修改常量数据
    auto mutable_val_lambda = [=]() mutable { val = 3;};  

    // 依然是const的lambda,不过没有改动引用本身
    auto const_ref_lambda = [&] { val = 3;};//引用本身并没有改变

    // 依然是const的lambda,通过参数传递val
    auto const_param_lambda = [&](int v) { v = 3;};
    const_param_lambda(val);

    return 0;
}
按值传递的lambda函数相当于从父作用域复制了所需的捕获变量,这点和thread传参类似,如果担心拷贝开销的话可以参数引用传递父作用域的变量。