网站首页 > 博客文章 正文
在 C++11 标准中增加了 lambda 表达式,先简单回顾一下 lambda 中的缺省捕捉,再看 C++20 对 this 的捕捉的改进。
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,同一个变量不能捕捉两次,不管是否按值还是按引用
C++20 中 lambda 对 this 的捕捉改进
在类的成员函数中定义 lambda 时,this 指针是个特殊情况。因为类的成员函数中,默认都可以通过 this 指针访问类的成员变量,因此在 C++11 中新增 lambda 的时候,要求 this 指针只能使用引用方式,并且要求使用 “ = ” 缺省按值捕捉时,其他变量按引用捕捉都应该使用 “ & ” 来表示引用,并且特别指出 [ =, this ] 的写法是不合法的。
但按引用方式访问类成员变量不一定能满足所有需求,因此在C++17中,增加了按值的方式访问类成员变量,也就是捕捉 *this 。
这样对按值还是按引用捕捉 this 带来了差异,因此在C++20中,要求对 this 的捕捉要显式说明,不在 “ = & ” 的缺省捕捉中。同时,原来的 [ =, this ] 语法是不合法的,现在也改成合法了。
#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
【往期回顾】
猜你喜欢
- 2025-08-03 C++语法进阶-字符:字符变量(char)
- 2025-08-03 c++26新功能—Read-Copy-Update
- 2025-08-03 为什么Linux之父那么讨厌C++ 他骂的这几点。句句扎心
- 2025-08-03 为什么Linux之父那么讨厌C++ 他骂的这几点!句句扎心
- 2025-08-03 20道qiao牛逼的c++/c面试题
- 2025-08-03 C++学习教程_C++语言随到随学_不耽误上班_0基础
- 2025-08-03 20天轻松入门《C++第四章——函数》——4经坛教育
- 2025-08-03 看完侯捷老师所有C++视频之后的总结
- 2025-08-03 C++11+ 泛型编程(模板)
- 2025-08-03 C++20并发库新成员jthread(续)
你 发表评论:
欢迎- 08-06nginx 反向代理
- 08-06跨表插入连续的日期,sheetsname函数#excel技巧
- 08-06初中生也能学的编程,不走弯路,先用后学
- 08-06find命令的“七种武器”:远不止-name和-type
- 08-06恶意代码常见的编程方式
- 08-06kali2021ping 外网不通
- 08-06因为一个函数strtok踩坑,我被老工程师无情嘲笑了
- 08-06hadoop集群搭建详细方法
- 10℃nginx 反向代理
- 最近发表
- 标签列表
-
- ifneq (61)
- 字符串长度在线 (61)
- googlecloud (64)
- powershellfor (73)
- messagesource (71)
- plsql64位 (73)
- vueproxytable (64)
- npminstallsave (63)
- #NAME? (61)
- promise.race (63)
- 2019cad序列号和密钥激活码 (62)
- window.performance (66)
- qt删除文件夹 (72)
- mysqlcaching_sha2_password (64)
- nacos启动失败 (64)
- ssh-add (70)
- yarnnode (62)
- abstractqueuedsynchronizer (64)
- source~/.bashrc没有那个文件或目录 (65)
- springboot整合activiti工作流 (70)
- jmeter插件下载 (61)
- 抓包分析 (60)
- idea创建mavenweb项目 (65)
- qcombobox样式表 (68)
- pastemac (61)
本文暂时没有评论,来添加一个吧(●'◡'●)