I have the following integral function with Simpson's rule:

typedef double real;
typedef real real_func(real);
real Integral(real_func func, real a, real b, unsigned int N = 1000)
{...}

It works like:

real myfunc(real x) { ... }
Integral(sin,1,2);
Integral(myfunc,1,2);

But does not work with a public class function:

class myclass{
public:  
    real classfunction(real);
};
real mylass::classfunction(real x) {...};

The following gives error:

myclass probe;
Integral(probe.classfunction,1,2);

The compiler error message is:
error: argument of type `real (EOS::)(real)'
does not match `real (*)(real)'

Recommended Answers

All 9 Replies

Pointers to functions and pointers to methods are not the same thing. A pointer to a method is really an offset into the class, not a real pointer with an address value. You need to make two overloads of the Integral() function. One that takes a function pointer and one that takes a method pointer:

#include <iostream>

typedef double real;

real Integral(real (*func)(real))
{
    return func(0);
}

template <typename ClassType>
real Integral(ClassType& obj, real (ClassType::*func)(real))
{
    return (obj.*func)(0);
}

class myclass{
public:  
    real classfunction(real);
};

real myclass::classfunction(real x)
{
    return 3.14;
};

real myfunc(real x)
{
    return 1.23;
}

int main()
{
    myclass probe;

    std::cout << Integral(myfunc) << '\n'
              << Integral(probe, &myclass::classfunction) << '\n';
}

An extra complexity with pointers to class members is that the pointer is defined on the class, but to use the pointer you need an object of that class to access the member. That is why the Integral() overload for the member pointer also has an argument for an object of the class type.

sorry , i am a beginner, I have 2 questions:
Why do you write:
template <typename ClassType>
why not:
template <class ClassType> ?
secondly:
It is not possible to solve this with only one "function identifier" parameter passing to the Integrae function?

Why do you write:
template <typename ClassType>
why not:
template <class ClassType> ?

Personal preference. They both mean and do the same thing in this case. I use typename instead of class because it makes me look like a hip C++ guru who is down with the latest language standard. ;)

It is not possible to solve this with only one "function identifier" parameter passing to the Integrae function?

Maybe. It really depends on what myclass::classfunction() is supposed to do. If it modifies the state of an object and you want to keep that modification, you need some way of passing or returning the object that the method pointer is called on. Otherwise you can create a dummy object in the Integral() function, call the method pointer on it and throw it away. But then I would ask why you want to use a method pointer in the first place when it makes no difference. :D

I asked, just by beauty, because the function is logically one object (mathematically).

I have another question about this:

template <class ClassType>
real Integral(ClassType& obj, real (ClassType::*func)(real), real lower_bound, real upper_bound)
{}

I understand that the first argumentum of the Integer function must be any class by reference.
The second argument must be a real to real member function, but it can be member of any class, how can I restrict that this function has to be member of a specified class only?

sorry, i think my question was stupid :)

With templates the overloading is not necessary,
and templates are more beautiful,
because with overloading you has to type
more or less the same code at least twice.
Now, your overloading use two input parameters instead of one,
therefore it is necessary to type the same code twice,
this is not beautiful.
Are there any solution in which
you not must to type the same code twice,
and it can act on normal and member functions too?

And how can I call your function in the calss?

class myclass{
real func1(real)
real func2(real a, real b) 
    { 
      return Integral(this, &myclass::func1, a, b); 
    } 
}

This is wrong! How can i use "this"?

how can I restrict that this function has to be member of a specified class only?

You can remove the template and use a specific class if there is no need for generality:

real Integral(myclass& obj, real (myclass::*func)(real), real lower_bound, real upper_bound)
{
    //...
}

Are there any solution in which
you not must to type the same code twice,
and it can act on normal and member functions too?

Not without being convoluted. The usage of normal and method pointers are different, so at the point of the call you need at least a specialization. You can pass that in as some variation of the strategy pattern, but it would probably be simpler to have two interfaces and one implementation if your integral algorithm does not need to call the pointers internally.

This is wrong! How can i use "this"?

this is a pointer, but Integral() takes a reference to an object. You need to dereference this first:

return Integral(*this, &myclass::func1, a, b);
Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.