lambda表达式的基本使用方法
基本结构
[]()mutable->int
{
return 1;
}
- capture 子句 (C++ 规范中也称为 lambda 引入器 。)
- 参数列表 选。 (也称为 lambda 声明符)
- 可变规范 选。
- exception-specification 选。
- trailing-return-type 选。
- lambda 正文。
Capture 子句
[] {};//不访问变量
[=] {};//按值捕获
[&] {};//通过引用捕获
显式声明
int a, b;
//引用捕获a,值铺货b
[a] {};
[&a, b] {};
[b, &a] {};
[&, b] {};
[=, &a] {};
类中
void S::f(int i)
{
[&, i]{}; // OK
[&, &i]{}; // ERROR: i preceded by & when & is the default
[=, this]{}; // ERROR: this when = is the default
[=, *this]{ }; // OK: captures this by value. See below.
[i, i]{}; // ERROR: i repeated
}
后跟省略号的捕获是包扩展,如此 可变模板 示例所示:
template<class... Args>
void f(Args... args)
{
auto x = [args...] { return g(args...); };
x();
}
//移动捕获
auto ptr = make_unique<int>(1);
//...
auto a = [ptr = move(ptr)]()
{
// use ptr
};
参数列表
在 C++14 中,如果参数类型为泛型,则可以使用 auto 关键字作为类型说明符。 此关键字告知编译器创建函数调用运算符作为模板。 参数列表中的每个实例 auto 都等效于不同的类型参数。
auto y = [] (auto first, auto second)
{
return first + second;
};
[&, n](int a,int b) mutable
{
m = ++n + a;
}(3,1);//执行表达式
可变参数
template<class... Args>
void f(Args... args)
{
auto x = [args...]{ return g(args...); };
x();
}
Lambda 正文
lambda 表达式的 lambda 主体是复合语句。 它可以包含普通函数或成员函数正文中允许的任何内容。 普通函数和 lambda 表达式的主体均可访问以下变量类型:
- 从封闭范围捕获变量,如前所述。
- 参数。
- 本地声明的变量。
- 类数据成员在类内声明并
this捕获时。 - 具有静态存储持续时间的任何变量,例如全局变量
可变规范
通常,lambda 的函数调用运算符是常量值,但使用 mutable 关键字会取消此操作。它不生成可变数据成员。 该 mutable 规范使 lambda 表达式的正文能够修改值捕获的变量。
int m = 0;
int n = 0;
//规范 mutable 允许 n 在 lambda 中修改
[&, n](int a) mutable { m = ++n + a; }(4);
作为参数
生成器
vector<int> v;
static int nextValue = 1;
// The lambda expression that appears in the following call to
// the generate function modifies and uses the local static
// variable nextValue.
generate(v.begin(), v.end(), [] { return nextValue++; });
//WARNING: this isn't thread-safe and is shown for illustration only
for_each
int evenCount = 0;
for_each(v.begin(), v.end(),
[&evenCount](int n)
{
cout << n;
if (n % 2 == 0) {
cout << " is even " << endl;
++evenCount;
}
else {
cout << " is odd " << endl;
}
});
find_if
const list<int>::const_iterator result =
find_if(numbers.begin(), numbers.end(), [](int n) { return (n % 2) == 0; });
constexpr
//constexpr lambda 表达式或将其用于常量表达式。
int y = 32;
auto answer = [y]() constexpr
{
int x = 10;
return y + x;
};
//如果 lambda 结果满足函数的要求constexpr,则 lambda 是constexpr隐式的:
auto answer = [](int n)
{
return 32 + n;
};
constexpr int response = answer(10);
//如果 lambda 是隐式或显式 constexpr的,并且你将其转换为函数指针,则生成的函数也是 constexpr:
auto Increment = [](int n)
{
return n + 1;
};
constexpr int(*inc)(int) = Increment;
\