【问题标题】:How to use std::transform with a lambda function that takes additional parameters如何使用带有附加参数的 lambda 函数的 std::transform
【发布时间】:2019-03-31 09:36:10
【问题描述】:

在 C++ 11(或更高版本)中,我可以使用 std::transform 和 lambda 函数来转换也采用其他参数的向量吗?例如,如何将param 传递给下面的 lambda 函数?

std::vector<double> a{ 10.0, 11.0, 12.0 };
std::vector<double> b{ 20.0, 30.0, 40.0 };
std::vector<double> c;
double param = 1.5;
//The desired function is c = (a-b)/param   
transform(a.begin(), a.end(), b.begin(), std::back_inserter(c),
          [](double x1, double x2) {return(x1 - x2)/param; });

std::transform 想要一个有两个输入参数的函数。我需要使用std::bind吗?

【问题讨论】:

  • 永远不需要使用std::bind。 Lambdas 可以做所有bind 可以做的事情,甚至更多。它真的应该被弃用并最终被删除。
  • @JesperJuhl 我认为至少有一个极端情况bind 可以而 lambdas 不能,不记得它是什么,我自己也从未遇到过,所以我只坚持“Lambdas can do everything”; )
  • @user463035818 有一个详细的边缘案例here
  • @JesperJuhl:我也不会弃用 std::bind,只要 open-std.org/jtc1/sc22/wg21/docs/papers/2017/p0573r0.html(缩写 lambdas)未获批准。 Lambda 目前带有很多语法噪音,有些人可能认为std::bind 在某些用例中更易于阅读。
  • @NathanOliver 谢谢你的链接。今天学到了一些新东西。

标签: c++ c++11 vector lambda


【解决方案1】:

您只需要在您的捕获列表中捕获参数:

transform(a.begin(), a.end(), b.begin(), std::back_inserter(c),
          [param](double x1, double x2) {return(x1 - x2)/param; });

通过引用捕获它也有效 - 如果 param 是一个大类,那将是正确的。但是对于双 param 来说很好。

【讨论】:

    【解决方案2】:

    这就是lambda capture 的用途。您需要在 lambda 的捕获块 ([]) 中指定 &amp;=param

    std::vector<double> a{ 10.0, 11.0, 12.0 };
    std::vector<double> b{ 20.0, 30.0, 40.0 };
    std::vector<double> c;
    double param = 1.5;
    //The desired function is c = (a-b)/param   
    transform(a.begin(), a.end(), b.begin(), std::back_inserter(c),
              [=](double x1, double x2) {return(x1 - x2)/param; });
    //         ^ capture all external variables used in the lambda by value
    

    在上面的代码中,我们只是按值捕获,因为复制一个 double 并拥有一个引用在性能方面几乎是一回事,我们不需要引用语义。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2019-02-10
      • 2016-04-02
      • 2021-03-04
      • 1970-01-01
      • 1970-01-01
      • 2011-09-27
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多