On this page I found a good example of function pointers in C++ (as well as of functors, but this question isn't about functors). Below is some copypasta from that page.
#include <iostream>
double add(double left, double right) {
return left + right;
}
double multiply(double left, double right) {
return left * right;
}
double binary_op(double left, double right, double (*f)(double, double)) {
return (*f)(left, right);
}
int main( ) {
double a = 5.0;
double b = 10.0;
std::cout << "Add: " << binary_op(a, b, add) << std::endl;
std::cout << "Multiply: " << binary_op(a, b, multiply) << std::endl;
return 0;
}
I understand the code in general terms, but there are a couple of things that I've always found confusing. Function binary_op()
takes a function pointer *f
, but when it's used, for example on line 19 binary_op(a, b, add)
, the function symbol add
is passed in, not what one would think of as its pointer, &add
. Now you may say that this is because the symbol add
is a pointer; it's the address of the bit of code corresponding to the function add()
. Very well, but then there still seems to be a type discrepancy here. The function binary_op()
takes *f
, which means f
is a pointer to something. I pass in add
, which itself is a pointer to code. (Right?) So then f
is assigned the value of add
, which makes f
a pointer to code, which means that f
is a function just like add
, which means that f
should be called like f(left, right)
, exactly how add
should be called, but on line 12, it's called like (*f)(left, right)
, which doesn't seem right to me because it would be like writing (*add)(left, right)
, and *add
isn't the function, it's the first character of the code that add
points to. (Right?)
I know that replacing the original definition of binary_op()
with the following also works.
double binary_op(double left, double right, double f(double, double)) {
return f(left, right);
}
And in fact, this makes much more sense to me, but the original syntax doesn't make sense as I explained above.
So, why is it syntactically correct to use (*f)
instead of just f
? If the symbol func
is itself a pointer, then what precisely does the phrase "function pointer" or "pointer to a function" mean? As the original code currently stands, when we write double (*f)(double, double)
, what kind of thing is f
then? A pointer to a pointer (because (*f)
is itself a pointer to a bit of code)? Is the symbol add
the same sort of thing as (*f)
, or the same sort of thing as f
?
Now, if the answer to all of this is "Yeah C++ syntax is weird, just memorise function pointer syntax and don't question it.", then I'll reluctantly accept it, but I would really like a proper explanation of what I'm thinking wrong here.
I've read this question and I think I understand that, but haven't found it helpful in addressing my confusion. I've also read this question, which also didn't help because it doesn't directly address my type discrepancy problem. I could keep reading the sea of information on the internet to find my answer but hey, that's what Stack Overflow is for right?