2

I'm working with some basic signal code, and I can't figure out how this function is passed in as an argument. I came across this code in the libsigc++ tutorial:

AlienDetector mydetector;
mydetector.signal_detected.connect( sigc::ptr_fun(warn_people) );

AlienDetector has this member variable:

sigc::signal<void> signal_detected;

And warn_people is a function with a simple print statement:

void warn_people() { printf("They're here!\n"); }

Is there an example in the standard library of using a function like this? How does the compiler understand to "look for" the function that is being passed in?

ross
  • 526
  • 5
  • 19
  • 1
    If the code used `sigc::ptr(warn_people())` then you would not be passing the function as a parameter, you would be passing the return value of the function, since you are then calling the `warn_people`-function. – zenzelezz Jun 15 '15 at 06:52
  • I understand that you're passing the function in, but how can a compiler take a function as an argument? Is there an example of something like this in the standard library? Clarifying my question with an edit. – ross Jun 15 '15 at 14:27
  • 2
    What it boils down to is _function pointers_. People more clever than me could give a detailed explanation as to the details of how they work, but you could (perhaps) get a basic idea from [this thread](http://stackoverflow.com/questions/840501/how-do-function-pointers-in-c-work), since it also applies to C++. – zenzelezz Jun 15 '15 at 20:44
  • That is a very helpful link zenzelezz! I think I may be able to answer this question on my own soon. A vote on my question would be icing on the cake. – ross Jun 15 '15 at 21:49

1 Answers1

2

It use a function pointer. Wikipedia has some sample code in C: https://en.wikipedia.org/wiki/Function_pointer#Example_in_C

Function pointers are useful when the actual function to call might not be known until runtime. For instance:

typedef void (*callback_func)(int);
callback_func foo_func;

void set_foo_func(callback_func callback) {
  foo_func = callback;
}

void call_foo_func() {
  foo_func(5);
}

void my_func(int a) {
   ...
}

int main() {
   set_foo_func(my_func);
   call_foo_func();

   return EXIT_SUCCESS;
}

Dereferencing is optional (or meaningless, depending on how you think about it) and I personally prefer it:

void call_foo_func() {
  (*foo_func)(5);
}

set_foo_func(&my_func);

That's just for a static function. It's a little more complicated for member functions. And libsigc++ has lots of very complicated code to do lots of useful things.

murrayc
  • 2,103
  • 4
  • 17
  • 32