【问题标题】:Passing lambda function as parameter C++将 lambda 函数作为参数传递 C++
【发布时间】:2018-10-02 06:06:12
【问题描述】:

我正在将 lambda 函数 R1 和 R2 传递给我的模板函数 F。但是,我不确定我这样做是否正确。

函数 F 应该使用主函数中的所有参数并执行相关计算(牛顿的根近似法)。

我是使用模板函数的新手。因此,任何帮助将不胜感激。

//main.cpp
    #include <iostream>
    #include "Funct.h"
    using namespace std;

    int main()
    {

        auto f1 = [](long double x) { return (x * x) - 2; };
        auto f2 = [](long double x) { return (2 * x);
        auto RV1 = F<long double>(1.0L,1.0E-20L,f1(1.0L),f2(1.0L));
        return 0;


    }

    //Funct.h
    #include <iostream>
    #include<cmath>
    template<typename T> T F(long double guess, long double tolerance,T ((*f)(const T x)), T((*df)(const T x)));
    template<typename T> T F(long double guess, long double tolerance,T ((*f)(const T x)), T((*df)(const T x)))
    {

    }

【问题讨论】:

  • 当您想将函数传递给 F 时,不应调用函数。

标签: c++ templates lambda


【解决方案1】:

首先,正如@tkausl 所提到的,当您将 lambdas 作为参数传递时,您不应该调用它们,因为这样会自动评估并产生值(在这种情况下为 long doubles),但您的函数需要一个函数作为范围。

相反,您应该在被调用函数本身(在本例中为 F)中调用作为参数提供的函数。

您可以使用std::function 来描述函数原型,从而避免“丑陋”的函数指针。

首先,您需要包含标准库中的&lt;functional&gt; 头文件。

那么你可以这样写:

template <typename T>
using Func = std::function<T(T)>;

template <typename T>
T F(long double guess, long double tolerance, Func<T> f, Func<T> df); 

其中std::function&lt;long double(long double)&gt;中括号内的类型表示函数参数的类型,括号前的类型是函数原型的返回类型;

【讨论】:

  • 由于F已经是一个模板,最好的解决方案是通过两个类型模板参数传递fdf,从而避免从std::function删除类型的开销。不会带来太多。
【解决方案2】:

你可能会使用:

template <typename F1, typename F2>
long double F(long double guess,
              long double tolerance,
              F1 f,
              F2 der)
{
    f(4.2); // call function
    der(4.2);
    // ...
}

用法类似于:

auto f = [](long double x) { return (x * x) - 2; };
auto derived = [](long double x) { return 2 * x; };
auto RV1 = F(1.0L, 1.0E-20L, f, derived);

【讨论】:

    【解决方案3】:

    这种老式风格可能仍然会有所帮助,例如在异步操作中。

    void AsyncOperator(bool(*callback)(void*, void*), void* param)
    {
       while(true)
       {
          if (specific_condition_is_met)
          {
             if (callback(any_result, param)==false)
                return;
          }
          else if (callback(any_result_again, param))
             break;
       }
    }
    

    【讨论】: