【问题标题】:How to pass a local variable to lambda function?如何将局部变量传递给 lambda 函数?
【发布时间】:2019-08-27 02:46:57
【问题描述】:

我有一个整数153,我需要判断他是否等于pow之和(digit,digits)。所以153 = 1^3 + 5^3 + 3^3 = 153 返回true

我选择使用基本循环查找位数,然后将所有整数推入一个向量中,这样我就可以使用 std::for_each 函数迭代并在每个元素上使用 pow()

我面临的问题是每个元素的变化。我还不想诉诸for-loop,但我似乎无法通过for_each 弄清楚如何做到这一点。

错误在代码中注释。

#include <iostream>
#include <vector>
#include <algorithm>
#include <cmath>
#include <numeric>

bool narcissistic(int value)
{
    int k{};
    std::vector <int> sum{};
    while (value > 0) {
        k++;
        sum.push_back(value % 10);
        value /= 10;
    }
    std::for_each(sum.begin(), sum.end(), [](int& n) {pow(n, k); }); // error: 'k' is not captured
                                                              // (warning) note: the lambd has no capture-default
    if (std::accumulate(sum.begin(), sum.end(), 0) == value) return true;
    return false;
}

int main() 
{
    std::cout << narcissistic(153) << std::endl;
    return 0;
}

【问题讨论】:

标签: c++ algorithm lambda c++14 stdvector


【解决方案1】:

你可以让lambda函数去捕捉k

  • 通过使用[k](int &amp;n) { pow(n, k); } 按值(lambda 函数获取副本)
  • 通过引用使用[&amp;k](int &amp;n) { pow(n, k); }

https://isocpp.org/wiki/faq/cpp14-language#lambda-captures 上阅读有关 lambda 捕获的更多信息

话虽如此,我不会使用std::vector 来解决您的问题。您可以直接使用unsigned int k = std::floor(std::log10(n)) + 1; 获取数字中的位数,并在您的while循环中累加总和。不过,请务必在开头检查 n > 0。

【讨论】:

    【解决方案2】:

    但我似乎无法通过 for_each 弄清楚如何做到这一点。

    你有几个问题

    • while-loop 中,您正在更改原来通过的value 这里
      value /= 10;
      
      因此,后者你不能与它在线比较。
      if(std::accumulate(sum.begin(),sum.end(),0) == value)
      
      您应该保留原始的value 以供后面的比较。
    • 其次,您需要将pow(n, k) 而非sum 向量相加为 它只包含传递的value 的各个数字。
      double sum{};   // since, std::pow returns the floating points 
      std::for_each(powVec.begin(), powVec.end(), [k, &sum](int n) { sum += std::pow(n, k); });
      //                                                            ^^^^^^^^^^^^^^^^^^^^^ -> sum the powers of digits
      //                                                    ^^^^^^ -> no need of taking reference here
      //                                           ^^^^^^^^^ -> capture `k` by value, `sum` by reference
      
    • 第三,std::accumulate(sum.begin(),sum.end(),0) == value 是 错误,因为此时 value 已经是 0 并且 std::accumulate 返回各个数字的总和(即 不是你想要的)

    也就是说,将程序更改为:(See online live)

    bool narcissistic(const int value)
    //                ^^^^ --> cons because, passed value can only read
    {
        int k{};
        std::vector<int> powVec{}; // named as a vector of power of digits in the `value`
        int value_copy{ value };   // copy of original value
        while (value_copy > 0) {
            k++;
            powVec.push_back(value_copy % 10);
            value_copy /= 10;      // work with the copy of value
        }
        double sum{};  // since, std::pow returns the floating points
        std::for_each(powVec.begin(), powVec.end(),
            [k, &sum](int n) { sum += std::pow(n, k); });
        //   ^^^^^^^^-->capture `k` by value `sum` by reference
        // if (std::accumulate(sum.begin(), sum.end(), 0) == value) return true; // not required
        return static_cast<int>(sum) == value;
    }
    

    您可以在此处阅读有关 lambda 的更多信息:

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-01-12
      • 1970-01-01
      相关资源
      最近更新 更多