C++ 中递归 Void Lambda 表达式的问题

A Problem with Recursive Void Lambda Expressions in C++

我想在函数中实现 递归 void lambda 表达式。我在下面创建了 C++ 片段来说明我的问题。 Lambda 是我想在 Func1 中构建的递归 void lambda 表达式。但是,当我用 g++ 编译时,我 运行 出现以下编译器错误:

Lambda_void.cpp: In function ‘void Func1(std::vector<int>&)’:
Lambda_void.cpp:6:10: error: variable or field ‘Lambda’ declared void
     void Lambda = [](std::vector<int> &A)
          ^~~~~~
Lambda_void.cpp: In lambda function:
Lambda_void.cpp:11:13: error: ‘Lambda’ was not declared in this scope
             Lambda(A);
             ^~~~~~
Lambda_void.cpp:11:13: note: suggested alternative: ‘__lambda0’
             Lambda(A);
             ^~~~~~
             __lambda0
Lambda_void.cpp: In function ‘void Func1(std::vector<int>&)’:
Lambda_void.cpp:14:5: error: ‘Lambda’ was not declared in this scope
     Lambda(A);
     ^~~~~~

将 lambda 变量声明从 void 更改为 auto 不会解决任何问题,因为编译器在第一次递归之前未识别变量类型。这里有任何可能的解决方法吗?为什么 g++ 不允许这样做?

#include <iostream>
#include <vector>

void Func1(std::vector<int> &A)
{
    void Lambda = [](std::vector<int> &A)
    {
        while (A.size() < 5)
        {
            A.push_back(1);
            Lambda(A);
        }
    };
    Lambda(A);
}

int main()
{
    std::vector<int> C;
    Func1(C);
    for (auto& i : C) {std::cout << i << " ";}
    std::cout << std::endl;
    return 0;
}

void 不起作用,因为 lambda 的类型不是 void.

将 lambda 转换为 std::function 并捕获对其的引用:

#include <iostream>
#include <vector>
#include <functional>

void Func1(std::vector<int> &A)
{
    std::function<void(std::vector<int>&)> Lambda = [&](std::vector<int> &A)
    {
        while (A.size() < 5)
        {
            A.push_back(1);
            Lambda(A);
        }
    };
    Lambda(A);
}

int main()
{
    std::vector<int> C;
    Func1(C);
    for (auto& i : C) {std::cout << i << " ";}
    std::cout << std::endl;
    return 0;
}

有关递归 lamda 函数的解释,请参阅 this 问题。您可以将 Lambda 声明为 std::function<void(std::vector<int>&)> 并在 lambda:

中捕获它
std::function<void(std::vector<int>&)> Lambda;
Lambda = [&Lambda](std::vector<int>& A) {
    while (A.size() < 5) {
        A.push_back(1);
        Lambda(A);
    }
};
Lambda(A);

由于内部 lambda 尚未实例化,您无法推断其 return 类型。 解决方法之一是将 lambda 本身作为参数传递 (Godbolt):

auto Lambda = [](std::vector<int> &A, auto self) -> void
{
    while (A.size() < 5)
    {
        A.push_back(1);
        self(A, self);
    }
};
Lambda(A, Lambda);

但这显然是多余的,所以更好的方法是只使用自由函数进行递归。