什么时候更喜欢lambda中的显式捕获而不是隐式捕获?

voi*_*ter 7 c++ lambda c++11

有时我会std::find_if在本地函数中执行(例如)具有5个局部变量(包括参数)的情况.但是,传入STL算法的lambda只需要访问其中的1个.我可以通过以下两种方式之一来捕获它:

void foo(int one, int two, int three)
{
    std::vector<int> m_numbers;
    int four, five;

    std::find_if(m_numbers.begin(), m_numbers.end(), [=](int number) {
        return number == four;
    });
}
Run Code Online (Sandbox Code Playgroud)

或者我可以这样做:

void foo(int one, int two, int three)
{
    std::vector<int> m_numbers;
    int four, five;

    std::find_if(m_numbers.begin(), m_numbers.end(), [four](int number) {
        return number == four;
    });
}
Run Code Online (Sandbox Code Playgroud)

(注意我没有编译此代码,对任何语法错误或其他错误道歉)

我知道隐式捕获是基于odr使用的规则,所以在功能和实现方面,我认为两者都是相同的.什么时候使用显式捕获而不是隐式捕获?我唯一的想法与封装原则有些相关:只能访问所需的东西,编译器可以帮助您确定何时访问变量.它还保持方法的本地状态(它的不变量,在执行期间函数的生命周期)更安全.但这些真的是实际问题吗?

是否存在使用显式捕获而不是隐式捕获的功能性原因?遵循什么是好的经验法则或最佳做法?

M.M*_*M.M 5

在运行时使用[=]or是最简单且最有效的[&],无需命名任何名称。

在这些情况下,正如这个答案所描述的,只有在使用 odr时才会捕获变量。换句话说,编译器只捕获需要的内容。

如果您指定捕获列表,则可能会发生两个差异:

  • 你忘记捕获 lambda 使用的东西
  • 你捕获了 lambda 不需要的东西。

在第二种情况下,如果按值捕获,则意味着对象被不必要地复制。

因此,我的建议是使用[][&]、 或 ,[=]除非您能针对特定情况找到一个很好的理由。一种这样的情况可能是,如果您想通过引用捕获一些变量,并通过值捕获一些变量。


pac*_*der 5

  • 显式捕获总是更可取的,因为它不容易出错
  • 最好使用 & 以防重物(不是简单的 int、double 等)
  • 当您计划在变量捕获范围之外使用 lambda 时,请使用 =。使用 & 获得对局部销毁变量的悬空引用是有风险的