何时在C 11 lambda的定义中捕获需要捕获的变量
When are explicitly-named variable captures necessitated in the definition of a C++11 lambda?
到现在为止,当查看c++11
样式的C lambda表达式时,我将所有这些都放在两个类别中:捕获和非捕捉。
非捕捉lambdas虽然对它们的写作方式有更多的限制,但在如何使用它们的方式上更加灵活 - 它们可以隐式转换为类似的函数销钉类型;他们不鼓励std::function<…>
的使用情况,他们的实施范围较小,不太可能引起副作用问题,等等。
但是,捕获的lambda可以以更广泛的方式写。诚然,他们没有赋予我刚才提到的所有这些好处。但是,捕获的Lambda通过从堆栈的进料函数呼叫呼叫插入式DAG的范围内与无数访问周围示波器的访问权分开来弥补了它可以解决的各种问题。
,就我的理解而言。当我使用捕获的lambdas时,当我需要一个和两个变量之间,我倾向于明确参考特定变量:
using lambda_t = std::function<std::add_pointer_t<void>(int)>;
lambda_t lambda_explicit = [&one, &another](int descriptor) {
return ::mmap(nullptr, one, PROT_READ, MAP_PRIVATE, descriptor, another);
};
…如果有两个以上,我更喜欢(不同等的句法OCD和Laziness(明确命名捕获而避免使用参考形式:
lambda_t lambda_everything = [&](int descriptor) {
return ::mmap(nullptr, one, PROT_READ, MAP_PRIVATE, descriptor, another);
};
…哪个请注意,更改Lambda捕获的形式并没有改变有关Lambda类型的明显内容 - 例如,呼叫签名是相同的。这是违反直觉的,因为看来捕获作品的许多方式被模糊地指定并且有点特定于特定的,与捕获表达式所提供的详细正式多样性成反比(或者是声明?或声明清单?不确定(您会看到的完整荣耀,如果您转到最后一个链接并向下滚动一点。
我什至没有碰到总体的多数可能性 - 我几乎总是只做:
- 根本没有捕获;
- 一个或两个明确命名的变量捕获逐参考;或
- 所有事物的偶然捕获:
[&]
我应该在哪些情况下使用一种形式的捕获?
哪种形式是特殊的,通常要避免?哪些有形的处罚 - 性能,代码大小,潜在的UB或其他任何东西?捕获表格是否有切实和/或简单的好处?
我应该竭尽所能使用一种形式的捕获?
当您局限于使用无状态功能时,捕获不是一个选项,而您仅限于1。通常是将回调注册到C语言API时的情况。
当您想将对象移动到捕获中时,必须将其移至命名捕获中,因此仅限于2。这在C 11中是不可能的。您需要C 14的广义lambda捕获。通用捕获也对不需要传达给外部的最初状态的可变lambdas也很有用(除非明确返回(。
此外,当您希望按值捕获一组变量,而另一种变量按参考捕获时,默认情况下最多可以捕获一个集合,并且必须显式捕获至少一组。也就是说,这可能是一个特殊情况。我不记得曾经需要这个。
我认为没有必要使用默认捕获,但是它可以节省大量的冗余键入。
我更喜欢使用命名捕获的原因,因为我不喜欢全局变量。它给出了lambda代码的范围。
,如果有许多变量,并且许多lambdas仅访问带有未命名的语法的一些变量,那么审核代码很快就变得不可能。好的,如果您的功能很小,有3个本地变量,那么很容易接受lambda可以看到所有三个变量,但是如果您有10个当地人,则在重新访问代码时浪费时间,试图了解哪个三个变量lambda实际上修改了。
- 用C++中的一个变量定义一个常量
- 变量定义到C++布尔值转换
- 未声明的标识符错误,但变量定义正确 (?)
- C++多线程程序:变量定义为类成员的隔离错误
- 将变量定义为静态时,为什么可以多次定义它
- 初始值设定项列表与构造函数赋值与变量定义
- 如何根据传递给函数的变量定义特征矩阵大小
- C++ 描述如何使用来简化变量定义
- 如何转发声明依赖于变量定义的类,而变体定义又依赖于模板化类?
- 是否修改其声明语句中的变量定义良好
- 使用类的其他成员变量定义类的成员变量数组
- 是否可以通过全局变量定义具有可变参数数的函数中的参数数量
- 元组 std::get() 不适用于变量定义的常量
- 全局使用变量定义和C 声明
- C++变量定义中的易失性类型量词位置
- 将变量定义为数组和正确的语法
- 多个,包括具有变量定义的头文件
- 调用构造函数,并将成员作为参数解析为变量定义
- 逗号分隔变量定义中关系前的序列
- 如何使用命名变量定义常量右值引用参数的默认值