2016-11-04 15 views
0

多変量関数でニュートン法のスニペットを試行し、std::bindstd::functionを使用しました。しかし、私は、このエラーメッセージは何を意味し、どのように私は私の現在のコードを修正する必要がありますか?C++でstd :: bindとstd :: functionを使用するとエラーが発生する

error: conversion from 'std::_Bind_helper&, int>::type {aka std::_Bind, int))(double, double, double)>}' to non-scalar type 'std::function' requested

エラーに貼り付けましたか。

#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

を '_2'に見えます'_1'とする。第二に、あなたは 'std :: bind'を使わず、ラムダだけを使っていると考えましたか? '[](double y){return ftest(1、y、2); } '私にバインドするよりもきれいに見えます。 – Yakk

答えて

3

ここで問題:

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

Fがタイプdoubleの単一の引数を取る関数であるが、あなたのバインド式が_2含むことである - 関数に渡された第二引数を指し、返品はbind()です。つまり、は第2のの引数です。基本的には、この関数オブジェクトを大まかに構築しています。

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

このオブジェクトには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); } 
+0

ありがとう、バリー。なぜラムダがここで好まれるのだろうか。 – Nicholas

+4

@Nicholasさて、バインドを動作させるためには、SOの質問+専門家のC++知識(私のGoogle-fooの5分)が必要でした。一方、ラムダは間違ってしまうのが難しいです。 –

+2

@Nicholas bindは本当にお勧めしません。それはラムダの前の日に発明された非常に複雑で直感的ではない獣です。このトピックを掘り下げたい場合は、この話を強くお勧めします:https://www.youtube.com/watch?v=zt7ThwVfap0 –

関連する問題