Reputation: 11628
I'm just learning about function pointers in C++. The following examples do all compile and return the expected result, but I was taught that example 3 was the way to go. Why do the other examples still work?
There is another thing that seemed strange are the examples f,g,h,i
which in contrast to the the examples above do not all work. Why don't they work, comparing to the examples 1-8?
int executeOperator1(int a, int b, int f(int,int)){
return f(a,b);
}
int executeOperator2(int a, int b, int f(int,int)){
return (*f)(a,b);
}
int executeOperator3(int a, int b, int (*f)(int,int)){
return f(a,b);
}
int executeOperator4(int a, int b, int (*f)(int,int)){
return (*f)(a,b);
}
int op(int x, int y){
return x+y;
}
int main(int argc, char *argv[])
{
int a = 2, b=3;
//the following 8 examples compile nicely:
cout << "a=" << a << " b=" << b << " res=" << executeOperator1(a,b,op) <<endl; //1
cout << "a=" << a << " b=" << b << " res=" << executeOperator2(a,b,op) <<endl; //2
cout << "a=" << a << " b=" << b << " res=" << executeOperator3(a,b,op) <<endl; //3
cout << "a=" << a << " b=" << b << " res=" << executeOperator4(a,b,op) <<endl; //4
cout << "a=" << a << " b=" << b << " res=" << executeOperator1(a,b,&op) <<endl; //5
cout << "a=" << a << " b=" << b << " res=" << executeOperator2(a,b,&op) <<endl; //6
cout << "a=" << a << " b=" << b << " res=" << executeOperator3(a,b,&op) <<endl; //7
cout << "a=" << a << " b=" << b << " res=" << executeOperator4(a,b,&op) <<endl; //8
//int f(int,int) = op; //does not compile
int (*g)(int,int) = op; //does compile
//int h(int,int) = &op; //does not compile
int (*i)(int,int) = &op;//does compile
return 0;
}
Upvotes: 0
Views: 111
Reputation: 6901
Function, like arrays when passed as an argument to a function, decays into a pointer. For eg: A function taking two int
parameters and returning an int
would have a type of int (*) (int, int)
.
But you can pass the function as reference as well, in which case you would have a type of int (&) (int, int)
.
To declare a value of type of above function pointer you would simply write :
typedef int (*FuncType) (int, int);
FuncType myFunc = op;
// OR
FuncType myFunc = &op;
The second way is usually preffered as it is more clear, but most of the compilers let the user do away with the first style.
Would recommend to go through below link: http://en.cppreference.com/w/cpp/language/pointer#Pointers_to_functions
Upvotes: 1
Reputation: 62563
All your examples work because of wonderful so-called pointer decay rule. A function name decays to a pointer to function in almost all contexts. (Decay here means that original type information is lost, and all what is left is the pointer. Arrays do decay to pointers too in certain contexts).
So all your examples are semantically the same thing, and I would not call any of them preferred.
And just for the fun of it, this would compile too:
int executeOperator_insane(int a, int b, int f(int,int)){
return (***************f)(a,b);
}
Upvotes: 2
Reputation: 206567
When you use:
int f(int,int);
in main
(or any place that is not an argument to a function), it declares f
to be a function, not a pointer to a function. Hence, you cannot use
int f(int,int) = op;
On the other hand,
int (*g)(int,int) = op;
declares g
to be a pointer to a function. Hence, it works.
When int f(int,int)
is used as an argument to a function, it is equivalent to sing int (*f)(int, int)
.
Upvotes: 0