C++ Error: no matching function for call

余生颓废 提交于 2019-12-11 02:00:03

问题


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

回答1:


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



回答2:


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.




回答3:


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



回答4:


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



来源:https://stackoverflow.com/questions/23093488/c-error-no-matching-function-for-call

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!