【问题标题】:Error using std::bind and std::function in C++ [duplicate]在 C++ 中使用 std::bind 和 std::function 时出错 [重复]
【发布时间】:2016-11-04 14:49:37
【问题描述】:

我尝试在多元函数上尝试牛顿方法的 sn-p 并使用 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;
}

【问题讨论】:

  • _2 看起来应该是 _1。其次,您是否考虑过不使用std::bind,而只使用lambda? [](double y){ return ftest(1,y,2); } 在我看来比 bind 干净。

标签: c++ c++11 std-function newtons-method stdbind


【解决方案1】:

这里的问题:

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

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

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

那个对象有两个参数。 std::function&lt;double(double)&gt; 不允许这样做 - 它要求您的可调用对象允许单个参数。

简单的修复方法是修复占位符:

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); }

【讨论】:

  • 谢谢,巴里。我想知道为什么 lambda 在这里更可取。
  • @Nicholas 好吧,需要一个 SO 问题 + 一些专家的 C++ 知识(或我的 Google-foo 5 分钟;))才能让绑定的东西工作。另一方面,lambda 很难出错。
  • @Nicholas bind 不是真的推荐。这是在 lambda 之前发明的一种非常复杂且不太直观的野兽。如果你想深入这个话题,我强烈推荐这个演讲:youtube.com/watch?v=zt7ThwVfap0
猜你喜欢
  • 1970-01-01
  • 2023-03-16
  • 1970-01-01
  • 2013-04-16
  • 1970-01-01
  • 1970-01-01
  • 2021-09-18
  • 2022-11-04
  • 1970-01-01
相关资源
最近更新 更多