C++20 新特性(11):lambda对this的捕捉改进

C++20 新特性(11):lambda对this的捕捉改进在 C 11 标准中增加了 lambda 表达式 先简单回顾一下 lambda 中的缺省捕捉 再看 C 20 对 this 的捕捉的改进

欢迎大家来到IT世界,在知识的湖畔探索吧!

在 C++11 标准中增加了 lambda 表达式,先简单回顾一下 lambda 中的缺省捕捉,再看 C++20 对 this 的捕捉的改进。

C++20 新特性(11):lambda对this的捕捉改进



欢迎大家来到IT世界,在知识的湖畔探索吧!

lambda表达式的缺省捕捉

lambda表达式中,可以显式捕捉指定的变量,也可以进行隐含的缺省捕捉,缺省捕捉有两种方式:

  • &:表示按引用的方式进行捕捉
  • =:表示按值的方式进行捕捉,具体变量的值会复制一个拷贝,这个拷贝是const不可修改的。注意,按值捕捉变量的值,是定义 lambda 时候的值,而不是执行 lambda 时候的值。

在使用了缺省捕捉的同时,也可以对指定变量进行显式捕捉,但这个时候,捕捉的方式应该是不一样的,例如缺省是按引用方式捕捉,那么可以指定某些变量时按值的方式进行捕捉,但不能再指定某些变量重复的按引用方式捕捉。

int n = 0; int k = 0; auto f1 = [ = ] { return n + k; }; // <1> OK,缺省按值捕捉 auto f2 = [ & ] { return ++n; }; // <2> OK,缺省按引用捕捉 auto f3 = [ =, k ] { return n + k; }; // <3> Error,缺省按值捕捉,不能再单个变量按值捕捉 auto f4 = [ =, &k ] { return n + k; }; // <4> OK,缺省按值捕捉,指定变量按引用捕捉 auto f5 = [ &, k ] { return n + k; }; // <5> OK,缺省按引用捕捉,指定变量按值捕捉 auto f6 = [ &, &k ] { return n + k; }; // <6> Error,缺省按引用捕捉,不能再单个变量按引用捕捉 auto f7 = [ k, k ] { return n + k; }; // <7> Error,同一个变量不能捕捉两次, auto f8 = [ k, &k ] { return n + k; }; // <7> Error,同一个变量不能捕捉两次,不管是否按值还是按引用

欢迎大家来到IT世界,在知识的湖畔探索吧!

C++20 中 lambda 对 this 的捕捉改进

在类的成员函数中定义 lambda 时,this 指针是个特殊情况。因为类的成员函数中,默认都可以通过 this 指针访问类的成员变量,因此在 C++11 中新增 lambda 的时候,要求 this 指针只能使用引用方式,并且要求使用 “ = ” 缺省按值捕捉时,其他变量按引用捕捉都应该使用 “ & ” 来表示引用,并且特别指出 [ =, this ] 的写法是不合法的。

但按引用方式访问类成员变量不一定能满足所有需求,因此在C++17中,增加了按值的方式访问类成员变量,也就是捕捉 *this 。

这样对按值还是按引用捕捉 this 带来了差异,因此在C++20中,要求对 this 的捕捉要显式说明,不在 “ = & ” 的缺省捕捉中。同时,原来的 [ =, this ] 语法是不合法的,现在也改成合法了。

欢迎大家来到IT世界,在知识的湖畔探索吧!#include <stdio.h> class SA { public: int m_x { 0 }; void func(); }; void SA::func() { int n = 0; int ret = 0; n = 1; m_x = 2; auto f1 = [ = ] ( int k ) -> int { // n = 10; // <1> 按值捕捉,不能修改 return n + k; }; n = 100; m_x = 200; ret = f1( 3 ); printf( "n %d, m_x %d, ret %d\n", n, m_x, ret ); n = 1; m_x = 2; auto f2 = [ =, this ] ( int k ) -> int { // <2> C++17不支持,C++20支持,访问类成员变量,要求显式捕捉 this // n = 10; m_x = 20; // <3> this按引用捕捉,可以修改 return n + m_x + k; }; n = 100; m_x = 200; ret = f2( 3 ); printf( "n %d, m_x %d, ret %d\n", n, m_x, ret ); n = 1; m_x = 2; auto f3 = [ =, *this ] ( int k ) -> int { // n = 10; // m_x = 20; // <4> this按值捕捉,不能修改 return n + m_x + k; }; n = 100; m_x = 200; ret = f3( 3 ); printf( "n %d, m_x %d, ret %d\n", n, m_x, ret ); n = 1; m_x = 2; auto f4 = [ & ] ( int k ) -> int { n = 10; return n + k; }; n = 100; m_x = 200; ret = f4( 3 ); printf( "n %d, m_x %d, ret %d\n", n, m_x, ret ); n = 1; m_x = 2; auto f5 = [ &, this ] ( int k ) -> int { // <5> this按引用捕捉,其实和缺省按引用捕捉时重复的,不过标准一直都要求允许 n = 10; m_x = 20; return n + m_x + k; }; n = 100; m_x = 200; ret = f5( 3 ); printf( "n %d, m_x %d, ret %d\n", n, m_x, ret ); n = 1; m_x = 2; auto f6 = [ &, *this ] ( int k ) -> int { n = 10; // m_x = 20; // <6> this 按值捕捉,不能修改 return n + m_x + k; }; n = 100; m_x = 200; ret = f6( 3 ); printf( "n %d, m_x %d, ret %d\n", n, m_x, ret ); return; } int main( int argc, char * argv[] ) { struct SA a1; a1.func(); return 0; }

编译和输出的结果为:

[smlc@test code]$ g++ -std=c++20 a11.cpp [smlc@test code]$ ./a.out n 100, m_x 200, ret 4 n 100, m_x 20, ret 24 n 100, m_x 200, ret 6 n 10, m_x 200, ret 13 n 10, m_x 20, ret 33 n 10, m_x 200, ret 15

【往期回顾】

C++20 新特性(10):字符串类型的改进

C++20 新特性(9):指针和数组相关的两个改进

免责声明:本站所有文章内容,图片,视频等均是来源于用户投稿和互联网及文摘转载整编而成,不代表本站观点,不承担相关法律责任。其著作权各归其原作者或其出版社所有。如发现本站有涉嫌抄袭侵权/违法违规的内容,侵犯到您的权益,请在线联系站长,一经查实,本站将立刻删除。 本文来自网络,若有侵权,请联系删除,如若转载,请注明出处:https://itzsg.com/108226.html

(0)
上一篇 1天前
下一篇 1天前

相关推荐

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

联系我们YX

mu99908888

在线咨询: 微信交谈

邮件:itzsgw@126.com

工作时间:时刻准备着!

关注微信