curiousexplorer
curiousexplorer

Reputation: 1237

Passing a function pointer by reference

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

Answers (4)

Jon Purdy
Jon Purdy

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

Joachim Isaksson
Joachim Isaksson

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

nos
nos

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

James McNellis
James McNellis

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

Related Questions