【问题标题】:Header for nested C++ lambda function嵌套 C++ lambda 函数的标头
【发布时间】:2016-11-22 05:16:12
【问题描述】:

考虑以下(简化的)示例,其中两个 lambda 函数相互调用,其中一个还接受另一个函数作为参数。我需要使用 lambda 函数,因为这些函数还会在彼此之间传递经过修改的嵌套函数。

#include <iostream>
using namespace std;

auto f = [](int n, auto h)
{
    if(n >= 5) return n;
    cout << "h is some function " << h(4.0) << end; 
    auto func = [](int m){ return m*h(m); }; // some nested function   
    return g(n+1,func);  
};

auto g = [](int n, auto h)
{
    if(n >= 5) return n;
    cout << "h is some function " << h(5.0) << end; 
    auto func = [](int m){ return m*h(m); }; // some nested function   
    return f(n+1,func); 
};

int main()
{
    auto initial_function = [](int m){ return m*m; };
    f(1, initial_function);
    return 0.0;
}

这将返回通常的错误未声明的标识符'g',这是由于没有头文件而导致的。所以我的问题是:声明两个 lambda 函数的正确语法是什么?

【问题讨论】:

  • 写老无聊的命名函数。
  • 您更新的问题仍然是关于 lambdas 的问题,在这种情况下完全不需要。答案仍然是“不要使用 lambdas”。
  • 另外,如果您正在与特定评论者交谈,请像这样标记他们的名字:@user56643,否则他们可能会或可能不会收到有关您的 cmets 的警报,
  • 谢谢@n.m。和@ildjarn,你当然是对的。用户@Mzhr 最后是我的问题。我不知道如何在“非 lambda 函数”之间传递函数,这就是我最初坚持使用 lambda 的原因。我会避免过多地抽象我的问题;)

标签: c++ c++11 lambda c++14 header-files


【解决方案1】:

您需要在 g 中捕获 lambda(反之亦然)。 gf指向(未命名)函数的变量。制作这些 lambdas 没有意义。当您需要本地范围内的函数时,Lambda 效果最佳。您必须将其中至少一个转换为函数并进行前向声明以使此代码正常工作

int f(int n);
auto g = [](int n)
{
     if(n >= 5) return n;
    return f(n+1); 
};

int f(int n)
{
    if(n >= 5) return n;
    return g(n+1);  
}

int main()
{
    f(1);
    return 0.0;
}

根据 OP 的编辑,可能 OP 需要的是

template<typename T1, typename T2>
auto g(int n, const T1& f, const T2& h)
{ 
    if(n >= 5) return n;
    cout << "h is some function " << h(5.0) << end; 
    return f(n+1); 
} 

被称为:

auto h = [](int m) { return m*m; };
auto f = [h](int m) { return n >= 5 ? n : return g(n+1, f, h); };
g(n, f, h);

【讨论】:

  • 建议的解决方案解决了示例,但不保留完全的通用性。我提到的函数 f 和 g 需要是 auto 类型的 lambda 函数,它们本身也将其他函数作为输入参数。请参阅我上面的修改示例。
  • @user56643 我根据您的编辑编辑了我的答案。但是仍然使用所有 lambdas 并没有多大意义。
【解决方案2】:

lambda 的类型没有很好的定义,所以没有一个直截了当的答案。我更喜欢@bashrc 的回答,但如果您坚持使用两个 lambda,这种变化可能会起作用:

extern int (*f)(int n);

auto g = [](int n)
{
    if (n >= 5) return n;
    return f(n + 1);
};

int (*f)(int n) = [](int n)
{
    if (n >= 5) return n;
    return g(n + 1);
};

int main()
{
    f(1);
    return 0;
}

【讨论】:

    【解决方案3】:

    使用 std::function 解决问题。

    #include <functional>
    #include <iostream>
    
    std::function<int(int)> f;
    std::function<int(int)> g;    
    
    int main()
    {
    
       f = [](int n)
       {
         if(n >= 5) return n;
         return g(n+1);  
       };
    
       g = [](int n)
       {
          if(n >= 5) return n;
          return f(n+1); 
       };
    
        std::cout << f(1) << std::endl;
        return 0;
    }
    

    【讨论】:

    • 我添加了#include 并运行代码。它返回错误:C++ 需要所有声明的类型说明符。
    • 在main()中移动f和g的赋值
    • 这会将所有内容切换到运行时多态性,这有点违背了目的。
    【解决方案4】:

    这适用于我的机器:

    #include <functional>
    #include <iostream>
    #include <stdio.h>
    using namespace std;
    
    extern function<int(int, function<int(int)>)> g;
    
    auto f = [](int n, function<int(int)> h)
    {
        if (n >= 5) return n;
        cout << "h is some function " << h(4.0) << endl;
        auto func = [h](int m) { return m*h(m); };   
        return g(n + 1, func);
    };
    
    function<int(int, function<int(int)>)> g = [](int n, function<int(int)> h)
    {
        if (n >= 5) return n;
        cout << "h is some function " << h(5.0) << endl;
        auto func = [h](int m) { return m*h(m); };   
        return f(n + 1, func);
    };
    
    int main()
    {
        auto initial_function = [](int m) { return m*m; };
        f(1, initial_function);
    
        getchar();
        return 0; // Return value of the function is int so its better to use 0 rather than 0.0
    }
    

    【讨论】:

    • 确实,这适用于问题的原始表述。见我上面的修改。函数 g 现在将另一个函数作为输入参数。问题是 std::function 不能将 'auto' 作为类型处理。如何解决这个问题?
    • 用户@Mzhr 终于回答了我的问题。我不知道如何在“非 lambda 函数”之间传递函数,这就是我最初坚持使用 lambda 的原因。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-02-06
    相关资源
    最近更新 更多