码迷,mamicode.com
首页 > 编程语言 > 详细

C++新特性 lambda

时间:2018-04-28 11:48:36      阅读:197      评论:0      收藏:0      [点我收藏+]

标签:...   fun   namespace   world   使用   table   for   nbsp   entry   

/*
C++新特性:
lambda表达式:是C++新特性最终要之一,实际上是提供了
一个类似匿名函数的特性,而匿名函数则是在需要的一个函数
,但是又不想费力去命名一个函数的情况下去使用的。
[捕获列表](参数列表)mutable(可选)异常属性->返回类型{
//函数体
}
上面的语法规则除了[捕获列表]内的东西外,其他部分都很好理解,
只是一般函数的函数名被滤去,返回值使用了->的形式进行。
所谓捕获列表,其实可以理解为参数的一种类型,lambda表达式
内部函数体在默认情况下是不能够使用函数体外部的变量的,
这时候捕获列表可以起到传递外部数据的作用。根据传递的行为,
捕获列表也分为以下几种:
1、值捕获:与参数传值类似,值捕获的前期变量可以拷贝,不同之处
在于,被捕获的变量在lambda表达式被创建拷贝,而非调用时候才拷贝:
void learn_lambda_func_1(){
int value_1 = 1;
auto copy_value_1 = [value_1]{
return value_1;
} ;
value_1 = 100;
auto stored_value_1 = copy_value_1();
//这时候,stored_value_1 == 1,而value_1 == 100
//因为,copy_value_1 在创建的时候就保存了了一份value_1 的拷贝。
我们使用auto来自动获取func的类型,这个非常重要。定义好lambda函数之后,
就可以当这场函数来使用了。
其中[]表示接下来开始定义lambda函数,中括号中间有可能会有参数,
之后的()填写的是lambda函数的参数列表{}中间就是函数体了。
lambda函数的用处:假如设计了一个地址簿的类。现在要提供函数查询
这个地址簿,可能根据姓名查询,可能根据地址查询,还有可能两者结合
,要是为这些情况都写一个函数,那么很麻烦。所以我们应该提供一个接口,能方便的让用户自己定义自己的
查询方式。
*/
#include<iostream>
#include <string>
#include <vector>

class AddressBook{
public:
 template<typename func>
 std::vector<std::string> findMatchAddress(func a)
 {
  std::vector<str::string> resaults;
  for (auto iter = _address.begin(); iter != _address.end(); ++iter)
  {
   if (func(*iter)){
    resaults.push_back(*iter);
   }
  }
  return resaults;
 }
private:
 std::vector<std::string>_address;
};

/*
我们可以发现上面findMatchAddresses函数提供的参数是funcc类型,
这是一个泛型类型。在使用过程中应该传入一个函数,,然后分别对
地址簿中的每一个entry执行这个函数,如果返回值为真那么表明这个
entry符合使用者的筛选要求,那么就应该放入结果当中,那么这个func
类型的参数如何传入?
*/
AddressBook gloabl_address_book;

std::vector<std::string> findAddressesFromOrgs(){
 std::vector<std::string> a;
 [](const std::string & addr){
  return addr.find(".org") != std::string::npos;
 };
 return a;
}

/*
可以看到,我们在调用函数的时候直接定义了一个lambda函数。其参数类型是:
const string& addr
返回值是bool类型。
如果用户要使用不同的方式查询的话,只要定义不同的lambda函数就可以了。
*/


void learn_lambda_func_1(){
 int value_1 = 1;

 auto func = [] {
  std::cout << "hello world" << std::endl;
 };

 func();

 auto  copy_value_1 = [value_1]
 {
  return value_1;
 };
 value_1 = 100;
 auto store_value_1 = copy_value_1();
 std::cout << store_value_1 << std::endl;
 std::cout << value_1 << std::endl;
 return;

}

int main(){
 learn_lambda_func_1();
 system("pause");
 std::string name;
 std::cin >> name;
 return gloabl_address_book.findMatchAddress{
  [&](const std::string& str){
   return name.find(addr) != string::npos;
  };
 }
 return 0;
}

/*lambda函数中的变量读取,上述列子中,
lambda函数使用的都是函数使用的都是函数体的参数和它内部的信息,
并没有使用外部信息。我们设想,从键盘读取一个名字,然
后用lambda函数定义一个匿名函数,在地址簿中查找有没有
相同名字的人。那么这个lambdaa函数势必就要能使用外部
block中的变量,所以我们就得使用变量截取功能。
(variable capture),从上述代码中看出,我们的lambda函数已经能使用外部作用域
中的变量name,这个lambda函数一个最大的区别是[]中间加入了&符号,
这就是要告诉编译器,要进行变量截取。这样lambda函数体就可以使用
外部变量。如果不加入任何符号,编译器就不会进行变量截取。
下面是各种变量截取的选项:
[]不截取
[&]截取外部作用域中的所有变量,并作为引用在函数体内使用
[=]截取外部作用域中的所有变量,并拷贝一份在函数体中使用
[=, &foo]   截取外部作用域中所有变量,并拷贝一份在函数体中使用,但是对foo变量使用引用
[bar]   截取bar变量并且拷贝一份在函数体重使用,同时不截取其他变量
[this]            截取当前类中的this指针。如果已经使用了&或者=就默认添加此选项。
*/

/*
lambda函数和STL
lambda函数的引入为STL的使用提供了极大地方便,


using namespace std;
v.push_back(1);
v.push_back(2);
//,,,
for (auto iter = v.begin(); iter != v.end(); ++iter){
 cout << *iter << endl;
}
//现在有了lambda函数你可以这么写:
vector<int> v;
v.push_back(1);
v.push_back(2);
//...
for_each(v.begin(), v.end(), [](int val)){
 cout << val << endl;
}
*/

C++新特性 lambda

标签:...   fun   namespace   world   使用   table   for   nbsp   entry   

原文地址:https://www.cnblogs.com/yjds/p/8966431.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!