0

Is there any way to pass a function as a parameter in C++, like the way that functions can be passed as parameters in C? I know that it's possible to pass a function as a parameter in C using function pointers, and I want to know whether the same is possible in C++.

Community
  • 1
  • 1
Anderson Green
  • 30,230
  • 67
  • 195
  • 328
  • 4
    Yes you can. But in C++ we tend to pass functors rather than function pointers as the compiler can optimize them much more efficiently. – Martin York Jan 08 '13 at 00:50
  • Why was this question downvoted? Is it vague, ambiguous, or subjective in some way? Is there anything I can do to improve it? – Anderson Green Jan 08 '13 at 00:50
  • 5
    "This question does not show any research effort" maybe? – Mooing Duck Jan 08 '13 at 00:51
  • 1
    @MooingDuck But I answered my own question - is posting questions and then answering them considered counter-productive for some reason? – Anderson Green Jan 08 '13 at 00:52
  • 1
    @AndersonGreen: That has nothing to do with what Mooing just said. – GManNickG Jan 08 '13 at 00:53
  • 1
    Answering your own question is totally fine. But this question is something that is very very easy to test or lookup yourself, either one. – Mooing Duck Jan 08 '13 at 00:53
  • @MooingDuck I just looked around on Stack Overflow and I noticed that no one had asked or answered this question yet, so I decided to answer it myself. – Anderson Green Jan 08 '13 at 00:56
  • 1
    @AndersonGreen: Lots of easy questions aren't on and do not belong on stackoverflow. They belong in a google search. – Mooing Duck Jan 08 '13 at 00:57
  • 1
    @AndersonGreen, just FYI: C++ comes very very close to being a superset of C. This means that generally, anything you can do with with C in C syntax, you can also do in C++ with the same syntax. The are some exception to that. Function pointers, however, work in C++ pretty much exactly the way they work in C, with the syntax you are familiar with from C. – DWright Jan 08 '13 at 00:57
  • @MooingDuck Should I vote to delete this question, then, even though it's gotten a lot of answers that may be helpful or informative to C++ beginners? – Anderson Green Jan 08 '13 at 01:00
  • 1
    Maybe I'm missing something here, but I don't see how this question invites debate, arguments, polling or discussion. Apart from all of these chatty-cathys in the comments of course. Reopening. – Shog9 Mar 12 '13 at 03:27

5 Answers5

7

You can do it like in C. But you can also do it the C++ way (C++11, to be exact):

// This function takes a function as an argument, which has no
// arguments and returns void.
void foo(std::function<void()> func)
{
    // Call the function.
    func();
}

You can pass a normal function to foo()

void myFunc();
// ...
foo(myFunc);

but you can also pass a lambda expression. For example:

foo([](){ /* code here */ });

You can also pass a function object (an object that overloads the () operator.) In general, you can pass anything that can be called with the () operator.

If you instead use the C way, then the only thing you can pass are normal function pointers.

Nikos C.
  • 50,738
  • 9
  • 71
  • 96
  • I was originally going to write an answer similar to this but you beat me by a couple seconds, so here's the example code I was going to use as an example: [Link](http://stacked-crooked.com/view?id=b101a2f2eaff463715b1553ed551b71f) – Rapptz Jan 08 '13 at 01:01
2

It's possible in C++ just as in C to pass functions as parameters but with a few differences: we can use function references instead of pointers, templates types in addition to variadic template arguments. For example:

Function references:

In C, we don't have the ability to pass objects by reference. This however is possible in C++:

void f( void (&)() ) {}

f( h );

The difference between references are pointers is subtle, but important. For instance, we can't pass NULL or 0 to a function expecting a reference; the argument must be satisfied with its type immediately. References are usually preferred in most cases over pointers.

Templates:

Templates allow us to generically pass functions with variable type attributes as parameters:

template <class T, class U>
void f( T (&)( U ) ) {}

The above signature accepts a function with any return type or parameter list (the only setback is that the function must take one argument).

In addition to this feature, we can also utilize varaidic templates to allow functions with variable-length parameter lists:

template <class T, class ...U>
void f( T (&)( U... ) ) {}

int h(int, int) { .. }
bool g(std::string) { .. }


f( h );
f( g );

The implementation of f can also use perfect forwarding if we are using U&&:

template <class T, class ...U>
void f( T (&fun)( U&&...) ) {

    // ...
    fun( std::forward<U>(u)... );

}

There are also lambdas which are commonly bound with std::function<T(U)>.

Community
  • 1
  • 1
David G
  • 94,763
  • 41
  • 167
  • 253
0

Yes, function pointers work exactly the same way in C++ as in C.

Carl Norum
  • 219,201
  • 40
  • 422
  • 469
0

Yes, like this:

#include <stdio.h>

typedef void (*my_func)(int);

void do_something (my_func f) 
{   
   f (10); 
}

void square (int j) 
{   
   printf ("squared: %d\n", j * j); 
}

void cube (int j) 
{   
    printf ("cubed: %d\n", j * j * j); 
}

int main (int argc, char *argv[]) 
{   
   do_something (square);   
   do_something (cube); 
}

The output is:

squared: 100
cubed: 1000

The typedef is to make the syntax for do_something() a bit more readable.

I would like to point out that, since you are using C++ already, it is much easier ways to achieve the same with virtual functions.

JvO
  • 3,036
  • 2
  • 17
  • 32
-1

Yes, it is possible.

I found a working example program (which can be tested and edited online, and illustrates the concept well): http://ideone.com/6kSTrp#view_edit_box

//this was taken from http://www.cprogramming.com/tutorial/function-pointers.html
#include <stdio.h>
void my_int_func(int x)
{
    printf( "%d\n", x );
}


int main()
{
    void (*foo)(int); //pointer to an int function
    foo = &my_int_func;

    /* call my_int_func (note that you do not need to write (*foo)(2) ) */
    foo( 2 );
    /* but if you want to, you may */
    (*foo)( 2 );

    return 0;
}
Anderson Green
  • 30,230
  • 67
  • 195
  • 328