深入浅出C++11(5)-- Lambda函数与表示式
2013-10-05 15:59
267 查看
先来看个数组排序的例子:
以下为Objective-c对数组排序的代码:
相同实现代码在C++里面实现如下:
比较两个实现,采用C++明显复杂的多,而且还需要额外实现一个函数对象。
当然C++中也可以采用函数指针实现:
但也需要额外实现一个函数, 总体感觉比较累赘
同时,用户经常希望能够在算法函数调用的附近定义一个临时函数, 虽然c++允许在函数内部定义类型, 但结构上也不简洁:
特别是当函数里面还需要访问外部变量或者参数, 就不太可行了, 虽然可以通过以下方式勉强达到, 但比较objective c中的block就觉得麻烦复杂。
Objective c
于是C++ 11也提出了语法上类似Objective c中block形式的lambda表达式支持。
一个 lambda 函数可以用如下的方式定义:
这个不具名函数的回返类型是 decltype(x+y)。
只有在 lambda 函数符合"return expression"的形式下,它的回返类型才能被忽略。在前述的情况下,lambda 函数仅能为一个述句。
在一个更为复杂的例子中,回返类型可以被明确的指定如下:
如果 lambda 函数没有传回值(例如 void ),其回返类型可被完全忽略。
定义在与 lambda 函数相同作用域的参数参考也可以被使用。这种的参数集合一般被称作 closure (闭包)。
根据以上lambda定义,以上sort可以转换成:
需要访问外部变量时:
是不是简洁了很多啊, 这就是lambda方便之处, 也弥补了c++在临时或局部函数上的不足。
若一个 lambda 函数被定义于某类型的成员函数中,则可以使用该类型对象的参考,并且能够访问其内部的成员。
这只有当该 lambda 函数创建的作用域是在 SomeType 的成员函数内部时才能运作。
在成员函数中指涉对象的 this 指针,必须要显式的传入 lambda 函数, 否则成员函数中的 lambda 函数无法使用任何该对象的参数或函数。
若是 lambda 函数使用 [&] 或是 [=] 的形式,this在 lambda 函数即为可见。
lambda 函数是编译器从属类型的函数对象; 这种类型名称只有编译器自己能够使用。
如果用户希望将 lambda 函数作为参数传入,该类型必须是模版类型,或是必须创建一个 std::function 去获取 lambda 的值。
使用 auto 关键字让我们能够存储 lambda 函数:
[/code]
以下为Objective-c对数组排序的代码:
NSArray* array = @[@1, @3 ,@5, @2, @4, @6]; NSArray *sortedArray = [array sortedArrayUsingComparator:^(id obj1, id obj2) { return <obj1 vs obj2> }];
相同实现代码在C++里面实现如下:
template <typename T> class CompareType{ public: bool operator()(T& t1, T& t2){ return t1 < t2; } }; //调用 void test(){ vector<int> v = {1,3,5,2,4,6}; CompareType<int> comp; std::sort(v.begin(), v.end(), comp); }
比较两个实现,采用C++明显复杂的多,而且还需要额外实现一个函数对象。
当然C++中也可以采用函数指针实现:
template <typename T> bool TypeCompare(T& t1, T& t2){ return t1 < t2; } //调用代码 void test(){ vector<int> v = {1,3,5,2,4,6}; std::sort(v.begin(), v.end(), TypeCompare<int>); }
但也需要额外实现一个函数, 总体感觉比较累赘
同时,用户经常希望能够在算法函数调用的附近定义一个临时函数, 虽然c++允许在函数内部定义类型, 但结构上也不简洁:
void test(){ class CompareType{ public: bool operator()(int& t1, int& t2){ return t1 < t2; } }; //调用 vector<int> v = {1,3,5,2,4,6}; CompareType comp; std::sort(v.begin(), v.end(), comp); }
特别是当函数里面还需要访问外部变量或者参数, 就不太可行了, 虽然可以通过以下方式勉强达到, 但比较objective c中的block就觉得麻烦复杂。
void test(){ int compTimes = 0; class CompareType{ private: int* mCompTimes; public: CompareType(int* v) : mCompTimes(v){} public: bool operator()(int& t1, int& t2){ (*mCompTimes)++; return t1 < t2; } }; //调用 vector<int> v = {1,3,5,2,4,6}; CompareType comp(&compTimes); std::sort(v.begin(), v.end(), comp); }
Objective c
void test(){ NSArray* array = @[@1, @3 ,@5, @2, @4, @6]; __block int compTimes = 0; NSArray *sortedArray = [array sortedArrayUsingComparator: ^(id obj1, id obj2) { compTimes++; return <obj1 vs obj2>; }]; }
于是C++ 11也提出了语法上类似Objective c中block形式的lambda表达式支持。
一个 lambda 函数可以用如下的方式定义:
[](int x, int y) { return x + y; }
这个不具名函数的回返类型是 decltype(x+y)。
只有在 lambda 函数符合"return expression"的形式下,它的回返类型才能被忽略。在前述的情况下,lambda 函数仅能为一个述句。
在一个更为复杂的例子中,回返类型可以被明确的指定如下:
[](int& v1, int& v2)->bool{ return v1 < v2; }
如果 lambda 函数没有传回值(例如 void ),其回返类型可被完全忽略。
定义在与 lambda 函数相同作用域的参数参考也可以被使用。这种的参数集合一般被称作 closure (闭包)。
[] // 没有定义任何变量。使用未定义变量会导致错误。 [x, &y] // x 以传值方式传入(预设),y 以传参考方式传入。 [&] // 任何被使用到的外部变量皆隐式地以参考方式加以引用。 [=] // 任何被使用到的外部变量皆隐式地以传值方式加以引用。 [&, x] // x 显示地以传值方式加以引用。其餘变量以参考方式加以引用。 [=, &z] // z 显示地以参考方式加以引用。其餘变量以传值方式加以引用。
根据以上lambda定义,以上sort可以转换成:
void test(){
vector<int> v = {1,3,5,2,4,6};
std::sort(v.begin(), v.end(), [](int& v1, int& v2)->bool{ return v1 < v2; });
}
需要访问外部变量时:
void test(){ vector<int> v = {1,3,5,2,4,6}; int compTimes = 0; std::sort(v.begin(), v.end(), [&compTimes](int& v1, int& v2)->bool{ compTimes++; return v1 < v2; }); }
是不是简洁了很多啊, 这就是lambda方便之处, 也弥补了c++在临时或局部函数上的不足。
若一个 lambda 函数被定义于某类型的成员函数中,则可以使用该类型对象的参考,并且能够访问其内部的成员。
[](SomeType *typePtr) { typePtr->SomePrivateMemberFunction(); };
这只有当该 lambda 函数创建的作用域是在 SomeType 的成员函数内部时才能运作。
在成员函数中指涉对象的 this 指针,必须要显式的传入 lambda 函数, 否则成员函数中的 lambda 函数无法使用任何该对象的参数或函数。
[this]() { this->SomePrivateMemberFunction(); };
若是 lambda 函数使用 [&] 或是 [=] 的形式,this在 lambda 函数即为可见。
lambda 函数是编译器从属类型的函数对象; 这种类型名称只有编译器自己能够使用。
如果用户希望将 lambda 函数作为参数传入,该类型必须是模版类型,或是必须创建一个 std::function 去获取 lambda 的值。
使用 auto 关键字让我们能够存储 lambda 函数:
//栈上 auto myLambdaFunc = []()->int { return 5;}; int v = myLambdaFunc(); //堆上 auto myOnheapLambdaFunc = new auto([]()->int { return 5;}); int v2 = (*myOnheapLambdaFunc)(); free(myOnheapLambdaFunc);
[/code]
相关文章推荐
- c++11 Lambda函数与表示式
- C++11 Lambda函数(匿名函数)
- C++11特性--Lambda函数
- C++11新特性:Lambda函数(匿名函数)
- C++11中的匿名函数(lambda函数,lambda表达式)
- C++11中的匿名函数(lambda函数,lambda表达式)
- C++11中的匿名函数(lambda函数,lambda表达式)
- 初窥c++11:lambda函数及其用法
- C++11新特性:Lambda函数(匿名函数)
- C++11中的匿名函数(lambda函数,lambda表达式)
- C++11新特性:Lambda函数(匿名函数)
- C++11新特性:Lambda函数(匿名函数)
- C++11中的匿名函数指针(lambda函数,lambda表达式)
- C++11新特性:Lambda函数(匿名函数)
- C++11中的匿名函数(lambda函数,lambda表达式)
- C++11中的匿名函数指针(lambda函数,lambda表达式)
- C++11中的匿名函数(lambda函数,lambda表达式)
- 函数-->指定函数--->默认函数--->动态函数--> 动态参数实现字符串格式化-->lambda表达式,简单函数的表示
- C++11新特性:Lambda函数(匿名函数)
- C++11中的匿名函数(lambda函数,lambda表达式)