c++中使用std::bind和std::函数出错

Error using std::bind and std::function in C++

本文关键字:std 函数 出错 bind c++      更新时间:2023-10-16

我尝试在多元函数上尝试牛顿方法的片段,并使用std::bindstd::function。但是我被一个错误卡住了

错误:从'std::_Bind_helper&, int>::type {aka .}转换std::_Bind, int))(双精度,双精度,到非标量类型'std::function'要求

这个错误信息是什么意思,我应该如何修复我当前的代码?

#include <iostream>
#include<functional>
#include<cmath>
double newton(std::function<double(double)> F, std::function<double(double)> f,
              double x=0, int maxiter=1000, double epsilon=0.001)
{
    int n = 0;
    while((n < maxiter) && (fabs(F(x)) > epsilon))
    {
        x = x - F(x) / f(x);
        n++;
    }
    return x;
}
// I'd like to fix x and z at 1 and 2 and find root for y
double ftest(double x, double y, double z) 
{
    return x * x + (y * y - 2 * y - 4) + z * z;
}
// Partial derivative of ftest with regards to y
double ftest1(double y) 
{
    return 2 * y - 2;
}
int main()
{
    using namespace std::placeholders;
    std::function<double(double)> F = std::bind(ftest, 1, _2, 2);
    std::function<double(double)> f = ftest1;
    std::cout << newton(F, f);
    return 0;
}

这里的问题是:

std::function<double(double)> F = std::bind(ftest, 1, _2, 2);

F是一个接受单个double类型参数的函数,但是您的绑定表达式涉及_2 -它引用传递给bind()返回的函数对象的第二个参数。也就是第二个参数。基本上,您正在构造这个函数对象,大致如下:

struct {
    template <class T, class U>
    auto operator()(T, U arg) {
        return ftest(1, arg, 2);
    }
};

该对象接受两个实参。std::function<double(double)>不允许这样做——它要求你的可调用对象允许一个参数。

简单的修复方法是修复占位符:
std::function<double(double)> F = std::bind(ftest, 1, _1, 2);

或者,更好的是,根本不使用bind(),而使用lambda:

std::function<double(double)> F = [](double y) { return ftest(1, y, 2); }