문제

I am trying to solve a quadratic equation using the bisection method. When trying to evaluate the roots I get this error: "no matching function for call".

#include "assign4.h"
#include <iostream>

using namespace std;

int main(int argc, char * argv[]){
   solution s;
   double root;

   cout << "Enter interval endpoints: ";
   cin >> s.xLeft >> s.xRight;

   cout << "Enter tolerance: ";
   cin >> s.epsilon;

   root = s.bisect (s.xLeft, s.xRight, s.epsilon, s.f, s.error);

   if (!(s.error))
      cout << "Root found at " << root << "\nValue of f(x) at root is: " << s.f(root);
   else
      cout << "The solution of a quadratic equation with coefficients: " << endl;
      cout << "a = " << a << ", b = " << b << ", c = " << c << endl;
      cout << "has not been found." << endl;

   return 0;
}

The error occurs where root = ... it seems to have a problem with my function f but I don't understand what is wrong. The following two bits of code are my class and class implementation files. We just started working with classes so I am uncertain if my problem lies there or simply in the above code.

#ifndef ASSIGN4_H
#define ASSIGN4_H

class solution {

public:
   double xLeft, xRight;
   double epsilon;
   bool error;

   double bisect(double, double, double, double f(double), bool&);
   double f(double);
};
#endif // ASSIGN4_H

//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

#include "assign4.h"
#include <iostream>
#include <cmath>

using namespace std;

double solution::bisect (double xLeft, double xRight, double epsilon, double func(double), bool& error) {
   double xMid;
   double fLeft, fRight;
   double fMid;

   fLeft = f(xLeft);
   fRight = f(xRight);

   error = (fLeft * fRight) > 0;
   if (error)
      return -999.0;

   while (fabs (xLeft - xRight) > epsilon) {
      xMid = (xLeft + xRight) / 2.0;
      fMid = f (xMid);

      if (fMid == 0.0)
         return xMid;
      else if (fLeft * fMid < 0.0)
         xRight = xMid;
      else
         xLeft = xMid;

      cout << "New Interval is [" << xLeft << ", " << xRight << "]" << endl;
   }

return (xLeft + xRight) / 2.0;
}

double solution::f (double x) {
   return ((5 * pow(x,2.0)) + (5 * x) + 3);
}
도움이 되었습니까?

해결책 3

If you want to use pointers to member functions.

Change

double bisect(double, double, double, double f(double), bool&);

to

double bisect(double, double, double, double (solution::*f)(double), bool&);

in declaration and definition.

Change the call from

root = s.bisect (s.xLeft, s.xRight, s.epsilon, s.f, s.error);

to

root = s.bisect (s.xLeft, s.xRight, s.epsilon, &solution::f, s.error);

This is what I have that compiles and links successfully for me.

 #include <iostream>
 #include <typeinfo>
 #include <math.h>

 using namespace std;

 class solution {

 public:
    double xLeft, xRight;
    double epsilon;
    bool error;

    double bisect(double, double, double, double (solution::*f)(double), bool&);
    double f(double);
 };

 using namespace std;

 double solution::bisect (double xLeft, double xRight, double epsilon, double (solution::*func)(double), bool& error) {
    double xMid;
    double fLeft, fRight;
    double fMid;

    fLeft = (this->*func)(xLeft);
    fRight = (this->*func)(xRight);

    error = (fLeft * fRight) > 0;
    if (error)
       return -999.0;

    while (fabs (xLeft - xRight) > epsilon) {
       xMid = (xLeft + xRight) / 2.0;
       fMid = (this->*func)(xMid);

       if (fMid == 0.0)
          return xMid;
       else if (fLeft * fMid < 0.0)
       {
          xRight = xMid;
          fRight = fMid;
       }
       else
       {
          xLeft = xMid;
          fLeft = fMid;
       }

       cout << "New Interval is [" << xLeft << ", " << xRight << "]" << endl;
    }

 return (xLeft + xRight) / 2.0;
 }

 double solution::f (double x) {
    return ((5 * pow(x,2.0)) + (5 * x) + 3);
 }

 int main(int argc, char * argv[]){
    solution s;
    double root;

    cout << "Enter interval endpoints: ";
    cin >> s.xLeft >> s.xRight;

    cout << "Enter tolerance: ";
    cin >> s.epsilon;

    root = s.bisect (s.xLeft, s.xRight, s.epsilon, &solution::f, s.error);

    if (!(s.error))
       cout << "Root found at " << root << "\nValue of f(x) at root is: " << s.f(root) << endl;
    else
    {
       cout << "The solution of a quadratic equation with coefficients: " << endl;
       // cout << "a = " << a << ", b = " << b << ", c = " << c << endl;
       cout << "has not been found." << endl;
    }
    return 0;
 }

다른 팁

The 4th parameter is a function pointer,

double bisect(double, double, double, double f(double), bool&);

When you call this function:

root = s.bisect (s.xLeft, s.xRight, s.epsilon, s.f, s.error);

While the member fiction double f(double) is not the same type as that parameter because this is C++ member function and not static, so the 'this' parameter is added this member function when compiling.

type add the static key word to the function.

The syntax for a function pointer is usually: double (*f)(double). Aside from that, you are attempting to pass a member function through a non-member-function pointer. Since your function does not use any member variables, the simplest solution would be to make it static:

class solution {
  // ...
  static double f(double);
};

I believe it has to do with your callback function. Typically you get that kind of compiler error when you use an incorrect function call. If you want this kind of callback function, you may want to look into function pointers.

http://www.cprogramming.com/tutorial/function-pointers.html

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top