Ошибка использования std::bind и std::function в C++

Я пытаюсь попробовать мой фрагмент метода Ньютона на многомерной функции и использовал std::bind а также std::function, Но я застрял на ошибке

ошибка: требуется преобразование из 'std::_Bind_helper&, int>::type {aka std::_Bind, int))(double, double, double)>}' в нескалярный тип '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;
}

1 ответ

Решение

Проблема здесь:

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() вообще и лямбда предпочитаю

std::function<double(double)> F = [](double y) { return ftest(1, y, 2); }
Другие вопросы по тегам