c++ - 通过 lambda 中的显式 this 参数访问捕获的变量
问题描述
从声明/函数/9.3.4.6/6.2 (我对如何引用标准中的特定句子表示歉意):
显式对象参数声明是带有 this 说明符的参数声明。显式对象参数声明应仅作为参数声明列表的第一个参数声明出现: (6.1) 声明成员函数 ([class.mem]) 的成员声明符,或 (6.2 ) 一个lambda 声明符 ([expr.prim.lambda])。
如果this
lambda 表达式允许作为显式对象参数,那么当我们同时捕获变量时会发生什么?
根据我的理解,如果我们在后台有 lambda:
[x = 2](this auto& func) { x = 4; }();
可能大致相当于:
class lambda01 {
private:
int x;
public:
constexpr lambda01(cons int& x_)
: x{x_} {}
constexpr void operator()(this lambda01& func) {
func.x = 4;
}
};
lambda04 lambda04_obj {2};
lambda04_obj.operator()();
如果是对的。
例如没有。1:
int x;
// is it:
[&x](this auto& func){ x = 4; }();
assert(x == 4);
// or:
[&x](this auto& func){ func.x = 2; }();
assert(x == 2);
- 两个表达式都有效吗?
- lambda 采用左值对象参数是否有效?
例如没有。2 以可变参数打印参数:
[]<typename... Args>(const Args&... args) {
[&](this auto func){
/** ... **/
};
}(1, 2, 3, 4);
从评论的表达中,哪一个是有效的?
(std::cout << args << '\n', ...)
(std::cout << func.args << '\n', ...)
- 两个都
- 两者都不
如果第二个选择是有效的,那么关于 1 个对象中可能的参数包的问题值得提出另一个问题。
简而言之,在带有显式对象参数的 lambda 中使用点运算符访问的捕获变量是否有效?
解决方案
该标准不允许:
对于通过副本捕获的每个实体,在闭包类型中声明了一个未命名的非静态数据成员。
如果它是“未命名的”,那么你不能命名它。有一种特定的语言会导致捕获的实体的名称转换为this
基于 - 的表达式,但仅此而已。
因此,您可以采用显式this
参数,捕获的实体的名称将自动使用该参数。但是您不能通过显式参数访问这些变量。
显式接受 lambda 的唯一原因this
是使用标准提供的接口:调用 lambda。又名:递归调用 lambda而不命名 lambda。
推荐阅读
- python - xkbcommon: 错误: 未能添加默认包含路径
- ionic4 - 离子4科尔多瓦构建
- c# - 函数的单元测试挑战
- mysql - 将 SQL 查询转换为使用 Laravel 查询生成器
- mysql - 无法添加或更新子行:外键约束失败
- android - 如何使活动背景完全透明(不是半透明)?
- java - Selenium - Maven/TestNG:我们如何在 Java 类中添加 testng 参数,同时添加“main 方法”来创建可执行的 /runnable.jar 文件?
- javascript - 仅当填充红色时,画布上的透明 div 才会留下较暗的区域
- python - 如何从kivy中的另一个页面删除小部件
- sql-server - 我需要代码来运行 SQL Server 查询,该查询通过 VBA 存储在我的本地驱动器中,并将数据获取到 Excel 工作表中