如何给lambda一个持续时间与lambda一样长的内部值?

时间:2015-04-12 23:04:58

标签: c++ c++11 lambda c++14

我希望有一个我可以在lambda内修改的变量,而不会影响封闭范围。表现得像这样:

std::vector vec = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 0 };
{
  auto sum = 0;
  std::for_each(vec.begin(), vec.end(), [sum](int value) mutable
  {
    sum += value;
    std::cout << "Sum is up to: " << sum << '/n';
  });
}

但是,我希望能够在不声明lambda之外的sum变量的情况下执行此操作。像这样:

std::vector vec = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 0 };

std::for_each(vec.begin(), vec.end(), [auto sum = 0](int value) mutable
{
  sum += value;
  std::cout << "Sum is up to: " << sum << '/n';
});

所以sum仅在lambda内可见,而不在封闭范围内。是否可以在C ++ 11/14中使用?

4 个答案:

答案 0 :(得分:10)

C ++ 14引入了广义Lambda Capture ,可以让你做你想做的事。

捕获将从init表达式的类型中推断出来,就好像是auto

[sum = 0] (int value) mutable {
    // 'sum' has been deduced to 'int' and initialized to '0' here.
    /* ... */
}

答案 1 :(得分:0)

如果您遇到C ++ 11(并且不能使用C ++ 14的lambda捕获表达式,请参阅@ Snps&#39;回答),那么您可以在lambda中声明一个静态变量,正如你在任何其他功能中所做的那样。示例如下:

#include <algorithm>
#include <vector>
#include <iostream>

int main()
{
    std::vector<int> vec = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 0 };
    std::for_each(vec.begin(), vec.end(), [](int value)
    {
        static decltype(vec)::value_type sum{};
        sum += value;
        std::cout << "Sum is up to: " << sum << '\n';
    });
}

答案 2 :(得分:0)

至少在我看来,有更好的方法可以做到这一点。您使用std::for_each,但使用它来模仿std::accumulate。后者是手头工作的明确选择:

#include <numeric>
#include <iostream>
#include <vector>

int main(){
    std::vector<int> vec = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 0 };

    std::accumulate(vec.begin(), vec.end(), 0, [](int sum, int val) {
        sum += val;
        std::cout << "sum is up to: " << sum << "\n";
        return sum; });
}

我不确定这对你是否真的很重要,但这不需要C ++ 11以外的任何功能。

答案 3 :(得分:0)

如果C ++ 14不可用,您可以将所有内容都包装在lambda中,该lambda将返回原始lambda,并立即调用它。

std::for_each(vec.begin(), vec.end(), []()
{
    auto sum = 0;
    return [sum](int value) mutable
    {
        sum += value;
        std::cout << "Sum is up to: " << sum << '\n';
    };
}());

这样,临时sum的生命周期很短。