Today I came across this piece of code:
int main() {
struct Foo {};
struct Bar {};
Foo(b)(int (Bar*c)); // ?
return 0;
}
I have absolutely no idea what is going on. My compiler (VC14) warns me about unused prototyped function?
What does this line do (declare a function: which name, what parameters and return type? How to call it?)
Foo(b)(int (Bar*c));
Thank you in advance for helping me out!
This declares a function called b
that:
int (Bar*c)
as its argument;Foo
.The type of the argument, int (Bar*c)
, is a pointer to a function that takes a pointer to Bar
and returns an int
. Here, c
is the name of the argument and can be omitted: int (Bar*)
.
Here is how you can call b
:
int main() {
struct Foo {};
struct Bar {};
Foo(b)(int (Bar* c)); // the prototype in question
int func(Bar*); // a function defined elsewhere
Foo result = b(func);
return 0;
}
This is not valid C (because the names Foo
and Bar
don't refer to types; you would have to use the struct
keyword or use a typedef).
In C++, this is a surprising but valid declaration. It declares b as a function returning Foo and taking an argument of type "(pointer to) function returning int taking an argument of type pointer to Bar".
In order to generate a readable type declaration, I've written the following code:
#include <typeinfo>
#include <iostream>
int main() {
struct Foo {};
struct Bar {};
Foo(b)(int (Bar*c));
std::cout << typeid(b).name();
return 0;
}
Then I've compiled it and filtered its output through c++filt
.
The result was:
main::Foo (int (*)(main::Bar*))
which is entirely clear.
Actually, my compiler (Clang 3.5) gives me the following warning:
warning: parentheses were disambiguated as a function declaration [-Wvexing-parse]
Which is more on point, as you are dealing with with Most vexing parse.
The following declaration:
Foo(b)(int (Bar*c));
declares a b
function pointer pointing to a function that returns Foo
and takes as an argument a function that returns int
and takes pointer to Bar
an an argument (e.g.: int (Bar*c)
).
Your compiler probably thinks this is a prototype of a function, thus the warning.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With