I know that using type alias and typedef make the code so readable, less error-prone and easy modify. However in this example I want to know this complicated type:
#include <iostream>
#include <typeinfo>
char ( * (* x() )[] )();
int main(){
std::cout << typeid(x).name() << std::endl;
}
As the rule of thumb says that I read it from inside through outside but I find it too confusing.
Can someone help me how to read it?
The output of GCC:
FPA_PFcvEvE
char - returning a char *
(* - of pointers to *---v ^
(* - returning a pointer to *---v ^ v ^
x() - a function `x` --^ v ^ v ^
)[] - an array *---^ v ^
)(); - functions *--^
And see https://itanium-cxx-abi.github.io/cxx-abi/abi.html#mangle.array-type , like:
FPA_PFcvEvE
^ - function (
^ - returning pointer
^ - to an array [
>< - with no dimension expression
^ - separator, end of array ]
^ - of pointers
^ - to functions (
^ - returning char
^ - (void) functions that take no arguments
^ - separator, end of function )
^ - (void) it's a function that takes on arguments
^ - separator, end of function )
Example:
#include <iostream>
char return_a() { return 'a'; }
char return_b() { return 'b'; }
char return_c() { return 'c'; }
char (* array_of_funcs_that_return_char[3])() = {
return_a,
return_b,
return_c,
};
char (* (*pointer_to_array_of_funcs_that_return_char)[3])() = &array_of_funcs_that_return_char;
char ( * (* x() )[3] )() {
return pointer_to_array_of_funcs_that_return_char;
}
int main() {
std::cout << (*x())[1](); // outputs 'b'
}