Reputation: 1237
Hi I am trying to learn some function pointers in C/C++ and I was trying to write the following C++ code with gcc on Ubuntu.
This code should execute the multiply or or the add function depending on the preprocessor flag -DADD or -DMULTIPLY provided during compilation
#include <iostream>
#include <iomanip>
//Adds two numbers
int add(int a, int b)
{
return a+b;
}
//Multiplies two numbers
int multiply(int a, int b)
{
return a*b;
}
//Function to set the correct function to be executed.
//All functions here should have the same signature.
void functionsetter( void (*ptr2fun)(int,int) )
{
#ifdef ADD
ptr2fun = add;
#endif
#ifdef MULTIPLY
ptr2fun = multiply
#endif
}
int main(int argc, char *argv[])
{
int a = 5;
int b = 6;
void (*foo)(int,int);
functionsetter(foo);
return 0;
}
I cannot figure out how to pass the function pointer foo
to the function-setter
function by reference. Can someone help me out on this.I am sure the declaration of
functionsetter
is wrong in the code, Please let me know how to fix it.
I am trying to compile this with g++ -O2 -g -Wall -DADD main.cpp -o main
Note: I want to use such preprocessor flags and function pointers in some other-code elsewhere. Please let me know if such a thing is a good idea / practice.
Upvotes: 5
Views: 12681
Reputation: 54981
Without using a typedef
, the syntax for a reference to a function pointer is:
void functionsetter(void (*&ptr2fun)(int, int)) { ... }
But it is generally simpler to create a typedef
for the pointer type:
typedef void (*FunctionPointer)(int, int);
void functionsetter(FunctionPointer& ptr2fun) { ... }
Or for the function type:
typedef void Function(int, int);
void functionsetter(Function*& ptr2fun) { ... }
Upvotes: 14
Reputation: 180917
First, you're not passing a function pointer reference to the method, you're just passing a function pointer. You need to change the method signature to
void functionsetter( void (*&ptr2fun)(int,int) )
Also, your method signature is void(*)(int,int)
in some places and int(*)(int,int)
in some, they should probably be the latter everywhere since your add and multiply methods return int
.
That said, since you're using C++, manipulating pointers in this manner isn't something I'd recommend, C++ has inheritance/virtual methods that can usually replace most function pointer use and makes the code much more readable and extensible.
Upvotes: 1
Reputation: 229108
You'd change your signature to:
void functionsetter( void (*&ptr2fun)(int,int) )
Note that the ptr2fun function pointer has the wrong signature, your add and multiply functions return an int, and so should ptr2fun
This becomes a lot easier if you use a typedef:
typedef int (*ptr2fun)(int,int);
void functionsetter(ptr2fun& func) { ...
Though, personally I'd just return the function pointer.
ptr2fun functionsetter()
{
#ifdef ADD
return add;
#endif
#ifdef MULTIPLY
return multiply
#endif
}
Upvotes: 1
Reputation: 355069
Use a typedef
:
typedef void (*MyFunctionPointer)(int,int);
void functionsetter(MyFunctionPointer& fp);
I want to use such preprocessor flags and function pointers in some other-code elsewhere. Please let me know if such a thing is a good idea / practice.
No, not really. It isn't clear from your example what you are trying to accomplish, but your implementation is rather unusual. Consider using virtual member functions or std::function
to switch function implementations at runtime, or (possibly) templates to switch them at compile-time. There's nothing wrong with using conditional compilation for static selection like this, but mixing that with function pointers is a bit odd.
Without a good understanding of the problem you are trying to solve, it's difficult to give good advice as to how best to solve it.
Upvotes: 7