Question

When you have a function (pointer) as an argument to another function in c++ does the function (that is in the argument) have to be a void function?

eg. Can you have a function like

void run(int (*method)(int, double, vector), int dimension)

here the function method returns an int not a void. I am also having difficulty with the vector. Should it be a &vector?

When I then call it in my main I have it as:

run(jacobi_method(Vnew, V, vec), dimension);

but it does not want to work. Thanks

No correct solution

OTHER TIPS

run(jacobi_method(Vnew, V, vec), dimension);

should be

run(jacobi_method, dimension);

When you have a function (pointer) as an argument to another function in c++ does the function (that is in the argument) have to be a void function?

No, it can be any type of function; as long as the code using it calls it correctly.

Should it be a &vector?

You mean, should it be a reference? Only you can decide. Is the function supposed to modify it? Then it should be a reference. If not, it's probably more efficient to pass by const reference rather than value.

run(jacobi_method(Vnew, V, vec), dimension);

That's trying to pass the result of calling the function, not a pointer to the function. You want

run(jacobi_method, dimension);

eg. Can you have a function like

void run(int (*method)(int, double, vector), int dimension)

Yes, that is ok, just remember that vector is a template, so it should be

void run(int (*method)(int, double, vector<some_type>), int dimension)

As for your calling,

run(jacobi_method(Vnew, V, vec), dimension);

You can't pass the arguments to the function pointer. You should call it as

run(jacobi_method, dimension);

Here is a complete working code:

    #include <vector>
    #include <iostream>

    using namespace std;

    int jacobi_method(int a, double b, vector<int> c)
    {
        cout << "jacobi_method: " << a << " " << b << endl;
        for(int i=0; i<c.size(); i++)
            cout << c[i] << endl;
        return 8;
    }

    void run(int (*method)(int, double, vector<int>), int dimension)
    {
        int result;
        vector<int> a;
        a.push_back(1337);
        a.push_back(1338);
        result = method(dimension,2.1,a);
        cout << "Result = " << result << endl;
    }

    int main()
    {
        run(jacobi_method, 2);
        return 0;
    }

Yes, it is possible to pass a non void return function as parameter. A full sample:

#include <iostream>

using namespace std;

int sum(int a, int b) {
    return a + b;
}

int substract(int a, int b) {
    return a - b;
}

void run(int (*f)(int a, int b), int a, int b) {
    int res = f(a, b);
    cout << "Result: " << res << endl;
}

int main()
{
    run(sum, 10, 5);
    run(substract, 10, 5);

    return 0;
}

Such definition is legal

void run(int (*method)(int, double, vector), int dimension)

But,

run(jacobi_method(Vnew, V, vec), dimension);

is equivalent to

int r = jacobi_method(Vnew, V, vec);
run(r, dimension);

so you should call:

run(jacobi_method, dimension);

About the vector question, passed by reference (Vector & vec or const Vector & vec for read only) is recommended, because passed by value (Vector vec) actually make a copy, which will lead to low efficient in most conditions.

So just pass vector by value only when you tend to make a copy. The same rule can apply to any other parameter passing, such as other containers and user defined objects

Yes you can have a function that accepts a pointer to another function with a specific signature:

void run(int (*method)(int, double, std::vector<int>), int dimension)
{
     std::vector<int> vec;   
     // put some values in the vector here
     int result = method(1, 2.5, vec);   // this will call the function
}

And the invocation:

int my_method(int x, double d, std::vector<int> v)
{
   int result;
   // function code here
   return result;
}

run(my_method, dimension);

But, if you want to pass a function with specific parameters to 'run' and also have the ability to change these original parameters inside 'run', then you need to pass in a functor that wraps the method and its arguments, so your 'run' will get the result based on the original parameters, and/or whatever changes 'run' made itself.

Let me know if this is what you really want.

The other posters have pointed out the mistake in your syntax, I'll answer the other question that you have: How do you specify the parameters for the function in question.

If you want to specify them at the moment that you construct the function pointer (as in your original post), your function's type should actually be int (*method)(). You don't expect anyone to be able to change the function parametrs through the pointer, and this is why your pointer is actually to a function accepting no parameters. If you want to re-use some function that you already have, and assign some parameters, and pass the function as a pointer, with the parameters that you assigned, what you need is std::bind. Some documentation on it: http://en.cppreference.com/w/cpp/utility/functional/bind

In essence, what this allows you to do, is to take one function pointer, pass some parameters to it, and get a new function pointer, which will call your original function, but with the parameters that you specified.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top