0

I have tried multiple google searches and help guides, but I'm out of ideas on this one. I have a function pointer that I am using as an argument for another function. Both functions are within the same class. However, I keep getting type conversion errors. I'm sure this is just a syntax problem, but I can't understand what the correct syntax is. Here is a simplified version of my code:

Header File

#ifndef T_H
#define T_H

#include <iostream>
#include <complex>

namespace test
{

class T
{
public:
    T();
    double Sum(std::complex<double> (*arg1)(void), int from, int to);
    int i;
    std::complex<double> func();
    void run();
};

}
#endif // T_H

Source File

#include "t.h"

using namespace test;
using namespace std;

//-----------------------------------------------------------------------
T::T()
{
}

//-----------------------------------------------------------------------
double T::Sum(complex<double>(*arg1)(void), int from, int to)
{
    complex<double> out(0,0);

        for (i = from; i <= to; i++)
        {
            out += arg1();
            cout << "i = " << i << ", out = " << out.real() << endl;
        }

    return out.real();
}

//-----------------------------------------------------------------------
std::complex<double> T::func(){
    complex<double> out(i,0);
    return out;
}

//-----------------------------------------------------------------------
void T::run()
{
    Sum(&test::T::func, 0, 10);
}

Whenever I try to compile, I get the following error:

no matching function for call to 'test::T::Sum(std::complex<double> (test::T::*)(),int,int)'
note:  no known conversion for argument 1 from 'std::complex<double> (test::T::*)()' to 'std::complex<double>(*)()'

Any advice appreciated. Or at least a link to a thorough site on how to use function pointers. I am using Qt Creator 2.6.2, compiling with GCC.

3
  • Thats not just any old function. Its a member function. Commented Jan 24, 2014 at 1:13
  • Change complex<double>(*arg1)(void) to complex<double>(T::*arg1)(void) Commented Jan 24, 2014 at 1:15
  • And I believe you'd call it like out += (this->*arg1)(); Commented Jan 24, 2014 at 1:24

3 Answers 3

3

Your Sum function expects pointer to a function. And then you try to call it with a pointer to a member function. Learn about pointers to members.

Sign up to request clarification or add additional context in comments.

Comments

1

The code itself is a bit messy, I'll only correct the grammer to make it work.

firstly, you shall change the function prototype from

double Sum(std::complex<double> (*arg1)(void), int from, int to);

to

double Sum(std::complex<double> (T::*arg1)(void), int from, int to);

Meaning that it is a pointer to class T's member.

Then, when calling the function, you cant just arg1(),

for (i = from; i <= to; i++)
{
    out += arg1();
    cout << "i = " << i << ", out = " << out.real() << endl;
}

you have to use (this->*arg1)();

for (i = from; i <= to; i++)
{
    out += (this->*arg1)();
    cout << "i = " << i << ", out = " << out.real() << endl;
}

2 Comments

Now the code doesn't support the plain use-case of passing a normal function anymore.
Good point. For the moment, I only need it to work for member functions. At a later revision, I may add an overload to allow normal functions. Possibly as a template function for maximum flexiblity. But I still have several thousand lines of code to debug after this. For now, I plan to keep it simple.
1

How to pass functions as arguments in C++? In general, use a template, unless you have very compelling reasons not do it.

template<typename Func>
void f(Func func) {
  func(); // call
}

On the call side, you can now throw in a certain amount of objects (not just pointers to functions):

Functors;

struct MyFunc {
  void operator()() const {
    // do stuff
  }
};

// use:
f(MyFunc());

Plain functions:

void foo() {}

// use
f(&foo) {}

Member functions:

struct X {
  void foo() {}
};

// call foo on x
#include <functional>
X x;
func(std::bind(&X::foo, x));

Lambdas:

func([](){});

If you really want a compiled function and not a template, use std::function:

void ff(std::function<void(void)> func) {
  func();
}

2 Comments

Turns out that I needed to learn about using pointers to member functions. I also like the idea of using a template which would allow for lambdas. I tried lambdas earlier, and ran into compiler errors. I think for the moment, I will simply write the function to allow pointers to member functions. In a later revision, I may add an overload that uses Sum() as a template function to allow lambdas. Thanks all for the great advice.
@NicholasBarczak You might want to check if your compiler supports C++11. gcc upwards of 4.7 does, clang upwards of 3.3 as well. Both require the -std=c++11 argument to be passed. MSVC kind of supports it, but there is the mess of versions and compiler pre-releases and what not.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.