Nicholas Barczak
Nicholas Barczak

Reputation: 67

C++ Function Pointer as Argument

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.

Upvotes: 0

Views: 994

Answers (3)

pmr
pmr

Reputation: 59811

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

Upvotes: 1

user534498
user534498

Reputation: 3984

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

Upvotes: 1

Wojtek Surowka
Wojtek Surowka

Reputation: 20993

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.

Upvotes: 3

Related Questions