Search code examples
c++classbisection

C++ Error: no matching function for call


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

Solution

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