如何将局部变量传递给 lambda 函数?

How to pass a local variable to lambda function?

我有一个整数153,我需要判断他是否等于pow(digit,digits的总和)。所以 153 = 1^3 + 5^3 + 3^3 = 153 returns 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;
}

可以让lambda函数捕获k

  • 通过使用 [k](int &n) { pow(n, k); }
  • 按值(lambda 函数获取副本)
  • 通过使用 [&k](int &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。

but I can't seem to figure out how to do it via the 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 已经 0std::accumulate returns 各个数字的总和(即 不是你想要的)

也就是说,把程序改成:(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 的更多信息: