类似普通类的数据成员,lambda的数据成员在lambda对象创建时被初始化
返回
返回
- 如果一个lambda体包含任何单一return语句之外的内容,且未指定返回类型,则编译器假定此lambda返回void;
只包含单一return语句时,编译器会根据体中的代码推导出返回类型。- 被推断为返回void的lambda不能返回值;此时如果需要返回能正常执行,需要明确指定lambda的返回类型
捕获列表
捕获列表
类似参数传递,变量的捕获方式也可以是值或引用。
- 只用于局部非static变量,
因为: lambda可以直接使用局部static变量 和 定义在当前函数之外的名字(全局变量);
对于lambda所在函数中的局部变量,必须通过捕获列表去捕获才能在lambda体中使用;- 引用方式捕获
当以引用方式捕获一个变量时,必须保证在lambda执行时变量是存在的;
在lambda体内使用此变量时,实际上使用的是引用所绑定的对象。- 值捕获时
值捕获的前提是变量可以拷贝;
与参数不同,被捕获的值是在lambda创建时拷贝,而不是调用时拷贝;- 应该尽量减少捕获的数据量,来避免潜在的捕获导致的问题;
而且,如果可能的话,应该避免捕获指针或引用。
参数传递
函数内的lambda,
- 函数自动传递给lambda表达式的变量,把变量放在参数列表()中。
- 函数没有自动传递给lambda表达式的变量,但是该变量在lambda内部需要使用,怎么办?使用捕获列表[ ]去捕获。
混合使用隐式捕获和显示捕获时
混合使用隐式捕获和显示捕获时
- 捕获列表中的第一个元素必须是一个&或=,此符号指定了默认捕获方式为引用或值。
- 显示捕获的变量必须使用与隐式捕获不同的方式。
何时使用函数?何时使用lambda?
何时使用函数?何时使用lambda?
- 对于那种在一两个地方使用的简单操作,lambda表达式是最有用的。
- 如果我们需要在很多地方使用相同的操作,通常应该定义一个函数,而不是多次编写相同的lambda表达式。
- 类似的,如果一个操作需要很多语句才能完成,通常使用函数更好。
- 如果lambda的捕获列表为空,通常可以用函数代替它。!!!
- 对于捕获局部变量的lambda,用函数来替换它就不是那么容易了;需要bind()函数 来 绑定参数。!!!
#include <iostream>
#include <string>
#include <vector>
#include <memory> // shared_ptr
#include <algorithm>
#define Print_FuncLine (cout << __func__ << " " << __LINE__ << endl)
using namespace std;
bool isShorter(const string &s1, const string &s2)
{
return s1.size() < s2.size();
}
void print(vector<string> &wo)
{
cout << "size: " << wo.size() << endl;
for (const string &s : wo)
{
cout << s << " ";
}
cout << endl
<< endl;
}
void elimDups(vector<string> &wo)
{
cout << "排序前" << endl;
Print_FuncLine;
print(wo);
//按字典排序
sort(wo.begin(), wo.end());
cout << "排序后" << endl;
Print_FuncLine;
print(wo);
//去除重复元素
//把不重复元素从前往后依次排列,并返回不重复区域之后第一个位置的迭代器
std::vector<std::string>::iterator end_unique = unique(wo.begin(), wo.end());
//删除掉不重复区域之后的元素
wo.erase(end_unique, wo.end());
cout << "去重后" << endl;
Print_FuncLine;
print(wo);
}
void biggies(vector<string> &wo, size_t sz)
{
//按字典排序,并删除重复元素
elimDups(wo);
//按长度排序,长度相同的维持字典序
//stable_sort(wo.begin(), wo.end(), isShorter);
stable_sort(wo.begin(), wo.end(),
[](const string &s1, const string &s2) {
return s1.size() < s2.size();
});
cout << "去重后 + 按字符串的长度排序,后" << endl;
Print_FuncLine;
print(wo);
//find_if()对输入序列中的每个元素调用给定的这个谓词
vector<string>::iterator bigitr = find_if(wo.begin(), wo.end(),
[sz](const string &w) {
return w.size() >= sz;
});
Print_FuncLine;
for_each(bigitr, wo.end(),
[](const string &s) {
cout << s << " ";
});
cout << endl
<< endl;
wo.erase(wo.begin(), bigitr);
cout << "去重后 + 按字符串的长度排序,后,且大于指定长度的字符串" << endl;
Print_FuncLine;
print(wo);
}
int main()
{
vector<string> words{"the", "quick", "red", "fox", "jumps",
"over", "the", "slow", "red", "turtle",
"abcdef", "abcdef", "abcdefg", "abcdefg"};
biggies(words, 4);
return 0;
}
[root@lwh testcpp]# ./test4.out
排序前
elimDups 28
size: 14
the quick red fox jumps over the slow red turtle abcdef abcdef abcdefg abcdefg
排序后
elimDups 35
size: 14
abcdef abcdef abcdefg abcdefg fox jumps over quick red red slow the the turtle
去重后
elimDups 45
size: 10
abcdef abcdefg fox jumps over quick red slow the turtle
去重后 + 按字符串的长度排序,后
biggies 62
size: 10
fox red the over slow jumps quick abcdef turtle abcdefg
biggies 70
over slow jumps quick abcdef turtle abcdefg
去重后 + 按字符串的长度排序,后,且大于指定长度的字符串
biggies 81
size: 7
over slow jumps quick abcdef turtle abcdefg
[root@lwh testcpp]#