怎么用wordpress建立自己的网站,加强校园网站建设,网站建设栏目标语口号,微信小程序推广软件C Lambda表达式 Lambda 捕获含有模板参数的Lambda表达式无模板参数的Lambda表达式 Lambda 捕获
captures是零个或多个捕获的逗号分隔列表#xff0c;可以选择以capture-default开头。捕获列表定义可从 lambda 函数体内访问的外部变量。唯一的捕获默认值是
#xff0c;… C Lambda表达式 Lambda 捕获含有模板参数的Lambda表达式无模板参数的Lambda表达式 Lambda 捕获
captures是零个或多个捕获的逗号分隔列表可以选择以capture-default开头。捕获列表定义可从 lambda 函数体内访问的外部变量。唯一的捕获默认值是
变量引用方式隐式捕获已使用的变量存储持续时间限于Lambda表达式内值引用方式隐式捕获已使用的变量存储持续时间限于Lambda表达式内。
如果存在任一捕获默认值则当前对象 (*this)可以隐式捕获。如果隐式捕获则始终通过引用捕获即使捕获默认值为。从C20开始当捕获默认值为 时不推荐使用 *this 的隐式捕获。
captures 中单个捕获的语法是
下面展示一些 内联代码片。 - identifier 简单的值引用捕获- identifier ... 简单的值引用捕获捕获是一个包扩展- identifier initializer 简单的值引用捕获捕获包括初始化器- identifier 简单的变量引用捕获- identifier... 简单的变量引用捕获捕获是一个包扩展- identifier initializer 简单的变量引用捕获捕获包括初始化器- this 当前对象的简单的变量引用捕获- *this 当前对象的简单的值引用捕获- ...identifier initializer 值引用捕获捕获是一个包扩展 包扩展包含初始化器- ...identifier initializer 变量引用捕获捕获是一个包扩展 包扩展包含初始化器如果capture-default 为 则后续的简单捕获不能以 开头。
#include iostreamusing namespace std;struct S2 { void f(int i, int j); };
void S2::f(int i, int j)
{[] {i i 1;}; // OK: by-reference capture defaultcout i i endl;// [, i] {i0; jj1;}; // error: assignment of read-only variable ‘i’[, i] {ji1;};cout j j endl;// [, i] {}; // Error: by-reference capture when by-reference is the default[, j] {ji1;};cout j j endl;[, this, i] {}; // OK, equivalent to [, i]
}int main() { S2 s1;s1.f(1, 2);cout endl;s1.f(9, 10);
}代码运行的屏幕输出
i 1
j2
j2i 9
j10
j10只有在块作用域或默认成员初始器中定义的 lambda 表达式才可以有一个默认捕获或不带初始器的捕获。对于此类 lambda 表达式其有效范围定义为一组封闭范围这个范围包括最内层封闭函数及其参数。这包括嵌套的块作用域和封闭 lambda 的作用域如果该 lambda 是嵌套的。
任何没有初始化程序的捕获除了 this-capture中的 identifier都是在 lambda 的到达范围内使用通常的非限定名称查找来查找的。查找的结果必须是在到达范围内声明的具有自动存储持续时间的变量或者是其对应变量满足此类要求的结构化绑定。该实体被显式捕获。
带初始器的捕获的行为就好像它声明并显式捕获一个变量这个变量使用类型说明符 auto 和相同的初始器声明。其声明区域是 lambda 表达式的主体即它不在其初始器设定的范围内但不包括下列情况
如果捕获是通过值引用则闭包对象引入的非静态数据成员是引用该变量的另一种方式 换句话说源变量实际上并不存在并且通过 auto 进行类型推导和初始化适用于该非静态数据成员如果捕获是通过变量引用则闭包对象的生命周期结束时引用变量的生命周期也结束。
这用于通过 x std::move(x) 等捕获来捕获仅移动类型。 这也使得可以使用 cr std::as_const(x) 或类似方法使const 引用捕获成为可能。
#include iostreamusing namespace std;int x 4;
auto y [r x, x x 1]()-int{r 2; return x * x;};int main()
{auto val y();cout x x endl;cout val endl;
}x6
25如果捕获表有一个默认捕获并且未显式捕获封闭对象如 this 或 *this或者自动变量或者结构化绑定那么它会隐式捕获实体 该实体在一个表达式中在potentially-evaluated表达式中命名。 该自动变量在lambda 主体中是odr-usable。结构化绑定有原子存储持续时间。
#include iostreamusing namespace std;void f(int x, const int ()[2] {}) { cout f1: x endl;} // #1
void f(const int x, const int ()[1]) { cout f2: x endl;} // #2struct NoncopyableLiteralType
{constexpr explicit NoncopyableLiteralType(int n) : n_(n) {}NoncopyableLiteralType(const NoncopyableLiteralType) delete;int n_;
};int main ()
{const int x 17;auto l0 []{ f(x); }; // OK: calls #1, does not capture xauto g0 [](auto a) { f(x); }; // same as aboveauto l1 []{ f(x); }; // OK: captures x (since P0588R1) and calls #1// the capture can be optimized awayauto g1 [](auto a) { f(x); }; // same as aboveauto g2 [](auto a) {int selector[sizeof(a) 1 ? 1 : 2] {};f(x, selector); // OK: is a dependent expression, so captures xcout g2 endl;};auto ltid []{ return typeid(x).name(); }; // OK: captures x (since P0588R1)// even though x is unevaluated// the capture can be optimized awayauto g3 [](auto a) {auto type typeid(a x).name(); // captures x regardless of// whether a x is an unevaluated operandcout g3: type endl;};auto g4 [](auto a) {int selector[sizeof(a) 1 ? 1 : 2] {};f(x, selector); // OK: is a dependent expression, so captures xcout g2 endl;};l1();g1(1);g2(1);g2(2);cout x id: ltid() endl;g3(4);g4(1);constexpr NoncopyableLiteralType w{42};auto l4 []{ return w.n_; }; // OK: w is not odr-used, capture is unnecessary// auto l5 []{ return w.n_; }; // error: w needs to be captured by copycout l4() endl;
}
f1:17
f1:17
f1:17
g2
f1:17
g2
x id:i
g3: i
f1:17
g2
42含有模板参数的Lambda表达式 - [captures ] front-attr (optional) (params ) specs (optional) exception (optional) back-attr (optional) trailing-type (optional) requires (optional) { body }- [captures ] { body }- [captures ] front-attr (optional) trailing-type (optional) { body } - [captures ] front-attr (optional) exception back-attr (optional) trailing-type (optional) { body } - [captures ] front-attr (optional) specs exception (optional) back-attr (optional) trailing-type (optional) { body }captures - Lambda表达式可以拥有零个或多个逗号分隔的捕获列表可以选择以捕获默认值开头。 lambda 表达式可以使用变量而不捕获它如果该变量是非局部变量或具有静态或线程局部存储持续时间在这种情况下无法捕获该变量或者是已使用常量表达式初始化的引用。
lambda 表达式可以读取变量的值而不捕获它如果变量 具有 const 非易失性整型或枚举类型并且已使用常量表达式进行初始化或者 是 constexpr 并且没有可变成员。 tparams - 模板参数的非空逗号分隔列表用于为通用 lambda 的模板参数提供名称。 t-requires - 给tparams 添加约束。 如果 t-requires 以属性说明符序列结尾则序列中的属性将被视为 front-attr 中的属性。 front-attr - 属性说明符序列适用于闭包类型的operator()。 params - 闭包类型的operator()的参数列表。 它可以有一个显式的对象参数。 specs - 以下说明符的列表每个说明符在每个序列中最多允许出现一次。
说明符意义mutable允许 body 修改通过复制捕获的对象并调用它们的非常量成员函数。如果存在显式对象参数则无法使用。constexpr显式指定 operator() 是 constexpr 函数。如果 operator() 满足所有 constexpr 函数要求则即使 constexpr 不存在operator() 也将是constexpr 。consteval指定 operator() 是立即函数。consteval 和 constexpr 不能同时使用。static指定 operator() 是静态成员函数。static 和 mutable 不能同时使用。如果 captures 不为空或者存在显式对象参数则无法使用。 exception - 为闭包类型的operator()提供动态异常规范或noexcept说明符。 back-attr - 属性说明符序列适用于闭包Closure类型的operator()类型因此不能使用noreturn属性。 Trailing-type - - ret其中 ret 指定返回类型。 require - 给闭包类型的 operator() 添加约束。 body - 函数体。
在 body 的开头隐式定义 __func __
无模板参数的Lambda表达式 - [captures ] tparams t-requires (optional) front-attr (optional) (params ) specs (optional) exception (optional) back-attr (optional) trailing-type (optional) requires (optional) { body }- [captures ] tparams t-requires (optional) { body }- [captures ] tparams t-requires (optional) front-attr (optional) trailing-type (optional) { body } - [captures ] tparams t-requires (optional) front-attr (optional) exception back-attr (optional) trailing-type (optional) { body } - [captures ] tparams t-requires (optional) front-attr (optional) specs exception (optional) back-attr (optional) trailing-type (optional) { body }