How to use Function Pointers in C++

Function pointers in C++ have a somewhat obtuse syntax and similarly confusing semantics. This tutorial will lay out the syntax and semantics for the most common use cases in a way that is comprehensible and easy to get to grips with. The description here is by no means exhaustive but in my experience it should cover about 90% of the things you would want to do as long as you are making appropriate use of Boost.Bind and Boost.Function or their std equivalents (as you should be).

Declaring function pointer variables

Non member functions


return_type (*varName)() = namespace::function; // no parameters
return_type (*varName)(paramType1, paramTypeN) = namespace::function;

This is pretty straightforward, just get the signature correct (return type and parameters) and supply the fully qualified name of the function to be stored. Also note that an & is not required to address the function although it can be included if desired, both forms are correct.

Member functions


return_type (Class::*varName)(paramType1, paramTypeN) = &Class::method;

Using the syntax above any method on the target class that matches the signature can be bound. It should also be noted that for member functions the & specifier cannot be omitted.

Typedefs for function pointer types


typedef return_type (*TypeName)(paramType1, paramTypeN);
typedef return_type (ExampleClass::*TypeName)(paramType1, paramTypeN);
Specifying a function pointer type is very syntactically similar to declaring a variable, essentially just replace the variable name with the desired type name. Outside of typedef declarations the type name is omitted, like when casting e.g.
static_cast<void(Class::*)()>(&Class::method)

Using function pointer variables

There are two types of function pointer that you can have: non-member function pointers and member function pointers. A non-member function pointer is to a function that is not part of a class (importantly it can execute without dependence on any data). Member function pointers are pointers to class member functions, the function cannot be executed without an instance of the class (because it is a member function and all).

Calling a non-member function pointer


void (*funcPtr)(paramType1, paramTypeN) = namespace::function;
funcPtr(parameter1, parameterN);

This is syntactically pretty nice, once you have stored the pointer you can call it exactly as if it was the function that you stored.

Calling a member function pointer


void (Class::*memberFuncPtr)() = &Class::method;

Class* ptrInstance = new Class();
(ptrInstance->*memberFuncPtr)();

Class refInstance;
(refInstance.*memberFuncPtr)();

The syntax here is not quite as nice as with the non-member variety, the main difference is having to enclose the name in parentheses and the dereference of the function pointer variable. An interesting thing to note here is that the function pointer stored can be used with any instance that is of the correct class type interchangeably.

Instructive Examples

To complement the generic examples I have given above what proceeds from here is a long code sample showing a number of specific examples of storing the values of different types of non-member and member functions. These include overloaded member and non-member functions along with class templates and non-member templates.


namespace
{
  int simple() { return 0; }
  float test1(int first, float second, char third) { return 0.0; }
  float test2(int first, float second, char third) { return 0.0; }

  template <typename T_Example>
  void templateExample(T_Example param) {}

  class Class
  {
  public: // interface
    void method(int var) {}
    void overload(int var) {}
    void overload(int first, float second) {}

  }; // class

  template <typename T_Example>
  class TemplateClass
  {
  public: // interface
    void templateDo(T_Example templateParam, int extraParam) {}

  }; // class

} // namespace

int main(int arg, char** argv)
{
  // non-member examples
  int (*simpleNonMember)() = simple;
  simpleNonMember();

  typedef float (*TestTypeFuncPtr)(int, float, char);

  TestTypeFuncPtr test1FuncPtr = test1;
  TestTypeFuncPtr test2FuncPtr = test2;
  test1(7, 12.5, 'c'); // directly
  test1FuncPtr(7, 12.5, 'c'); // through the function pointer
  test2FuncPtr(11, 857.2, 'r');

  // non-member template examples
  void (*templateExampleFuncPtr1)(int) = templateExample<int>;
  void (*templateExampleFuncPtr2)(float) = templateExample<float>;
  templateExampleFuncPtr1(7);
  templateExampleFuncPtr2(7.f);

  // member examples
  Class* classPtr = new Class();
  Class classRef;
  void (Class::*overload2FuncPtr)(int, float) = &Class::overload;
  (classRef.*overload2FuncPtr)(0, 2.f);

  typedef void (Class::*ClassIntParamTypeFuncPtr)(int);
  ClassIntParamTypeFuncPtr overload1AndMethodFuncPtr = nullptr;
  overload1AndMethodFuncPtr = &Class::method;
  overload1AndMethodFuncPtr = &Class::overload;
  (classPtr->*overload1AndMethodFuncPtr)(7);
  (classRef.*overload1AndMethodFuncPtr)(7);

  // template class member examples
  TemplateClass<float>* templateClassPtr = new TemplateClass<float>();

  typedef void (TemplateClass<float>::*TemplateDoTypeFloat)(float, int);
  TemplateDoTypeFloat templateDoFuncPtr = &TemplateClass<float>::templateDo;
  (templateClassPtr->*templateDoFuncPtr)(11.f, 5);

} // main

12 Responses to “How to use Function Pointers in C++”


  1. This is a HUGE MESS!
    Everything is overcomplicated and not explained AT ALL!
    Saying that “This is pretty straightforward,” DOES NOT MAKE IT straightforward. You are saying these because you can’t ACTUALLY explain what is happening.

    Mixing everything into one big garbage-bin is the top of it.
    Imagine I mix you chocolate cake, mushed potato and shit into one plate. After all, it is in the same region!

    You need to explain EVERY-SINGLE-WORD, NAME, STATEMENT ONE-BY-ONE ON EVERY LINE.

    Unhappy
    April 16th, 2014
    • Hi there Unhappy,

      I’m sorry you didn’t find the tutorial helpful, the syntax for function pointers IS horrid and I must confess that what I write is targeted at more intermediate level C++ developers. The style I write in is to show how to use a language construct for the most common use cases and I skip detailed explanation with the assumption that the reader is already familiar. There are many other sources available that will take things more slowly and in detail if that is to your preference e.g. (http://www.cprogramming.com/tutorial/function-pointers.html). Thanks for the feedback.

      radman
      April 17th, 2014
    • I disagree with the sentiment “you need to explain every single word, name and statement”. In my opinion, a tutorial on function pointers comes with an implicit caveat that you should understand functions, pointers, and their syntax/usage.

      Radman I’ve found your tutorials quite helpful, particularly boost::bind, and I think understanding raw function pointers is absolutely a prereq.

      I might have also mentioned the ability to return function pointers from other functions, another area where the syntax is truly *miserable*, but remains a useful construct:

      boolean (*f(const string &))(const string &, int);

      A quick:

      typedef boolean (*ReturnFuncP)(const string &, int)

      Makes the above declaration at least a little easier to parse:

      ReturnFuncP f(const string &);

      Talk about opaque..

      Enelsk
      August 2nd, 2014
  2. Good … for reviewing syntax, covers almost everything, required before diving in boost tutorial ..

    Happy
    April 21st, 2014
  3. Hi. This is the best website I find about pointer to function. But, my problem is about how to pass a pointer, which is pointing to one of the class member function, into one member function of this class? Thanks.

    Yong Yang
    February 20th, 2015
    • Hi,

      It is quite inconvenient to do what your requesting without involving std::function or boost::function (they’re syntactically the same). Without these you would need to pass both the member function pointer AND a pointer to an instance of the class that it’s from. With std::function you simply initialise that object appropriately (say from a std::bind) and pass it through. Check out my boost::bind tutorial for some more info on that and cplusplus.com for more on std::function.

      radman
      February 20th, 2015
  4. Very well layed out. You may need a bit of experience with function pointers in C to fully appreciate the various options explained above for C++, however from that standpoint, this how-to is excellent.

    Appreciative
    March 18th, 2016
  5. Very well explained.
    Especially those parts in the beginning where you made it clear how to declare the entire scope resolution stuff.

    iman
    June 15th, 2016
  6. I agree with unhappy. This is terrible, the examples are not explained. A sinlge one liner would have done.

    Rahul
    May 19th, 2017
  7. Fantastic article, cleared so many queries of mine.

    Anuj Kumar
    July 28th, 2017
  8. Great article.

    Greybeard
    August 23rd, 2017

Leave a Comment