【问题标题】:In C++ Lambda Expressions, why would one prefer capturing by value over passing as arguments? [duplicate]在 C++ Lambda 表达式中,为什么人们更喜欢按值捕获而不是作为参数传递? [复制]
【发布时间】:2019-12-04 13:23:09
【问题描述】:

假设我会使用 Lamdba 函数来定义函数内的函数以更好地构建代码,在什么情况下有人可能更喜欢第二个选项而不是第一个选项,因为后者显然不太可重用,因为不能传递不同的参数?

int main() {
    int foo = 1;
    int bar = 4;

    //Passing as Parameters
    auto add = [](auto a, auto b) {
        return a + b;
    };
    std::cout << "Add: " << add(foo, bar) << std::endl;

    //Capturing by value
    auto multiply = [=]() {
        return foo * bar;
    };
    std::cout << "Multiply: " << multiply() << std::endl;

    return 0;
}

【问题讨论】:

  • 第二个 lambda 不需要参数,第一个需要两个参数。您可以将 lambda 作为回调传递给另一个函数,而另一个函数使用给定值调用 lambda,例如std::copy_if 需要一个带有一个参数的函数。
  • 我首先反对将 add 设为 lambda,它应该是一个普通函数,这使得它更加可重用,因为它可以在其他函数中使用。
  • 在函数中定义函数并不是 lambdas 的真正用途:如果 C++ 想要允许在函数中定义函数,我们可以在没有 lambdas 的情况下做到这一点。特别是,您的示例/参数是关于一个纯函数(一个没有状态的函数),而 lambdas 最显着的好处是允许将状态方便地捕获到(有状态的)函子中。捕获状态对于编写无状态函数没有用也就不足为奇了。您仍然可以为此使用 lambda,但不要期望它们的所有设计方面都是相关/有用的......

标签: c++ c++11 lambda


【解决方案1】:

按值捕获将值直接存储在 lambda 中。在该 lambda 的所有调用中都可以访问这些值。

如果您的 lambda 接受参数,则每次都必须提供值。

这允许您将 lambda 传递给不允许传递参数的事物,或传递不同数量的参数。例如,您可以将带有捕获变量的 lambda 传递给 std::for_each,并让 lambda 对捕获的值提供的元素进行操作:

std::vector<int> vi={1,2,3,4,452,99};

auto x=56;

std::for_each(vi.begin(),vi.end(),[=](int i){
  std::cout<<x+i<<std::endl;
});

【讨论】:

    【解决方案2】:

    当函数被传递给另一个函数时,例如标准库算法要求函数具有参数。

    【讨论】:

      猜你喜欢
      • 2012-12-25
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-11-25
      • 2015-08-13
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多