Ошибка использования 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); }