I got this declaration from https://en.cppreference.com/w/cpp/language/scope, but don't know how to parse this declaration even there is a comment below.
my questions is how to parse the declaration statement (I see it as a function pointer to a function protocol like "int[3] foo(int n)" or "int foo(int n)[3] --- they are illegal in C++ )? Then, how can I construct a concrete function which can be assigned to this function pointer? Thanks.
const int n = 3;
int (*(*f2)(int n))[n]; // OK: the scope of the function parameter 'n'
// ends at the end of its function declarator
// in the array declarator, global n is in scope
// (this declares a pointer to function returning a pointer to an array of 3 int
It's a pointer to a function taking an int
and returning a pointer to an int
array of size three.
All the comment is saying is that there are two n
identifiers in play here. The [n]
(in array declarator) is using the const int
3, not the parameter to the function (which is in the function declarator).
Starting in the middle, with each segment being included in the subsequent bullet point as ...
:
f2
is a pointer, (*f2)
....(int)
.int
array of size three, int (*...)[3]
.You can form a concrete function for it as per the following complete program, which output the first element, 42
:
#include <iostream>
const int n = 3;
int (*(*f2)(int n))[n];
int (*g2(int))[n] {
static int x[::n] = { 42 }; // Use outer n, not the parameter.
return &x; // since C++ has no VLAs. This
// means parameter is not actually
// needed in this test case, though
// it may be in more complicated
// tests.
}
int main() {
f2 = &g2; // Assign concrete function to pointer.
auto y = f2(3); // Call via pointer, get array.
std::cout << *(y[0]) << '\n'; // Deref first element to get 42.
}
Having said that, I would be rather curious if one of my colleagues submitting something like that for a code review, at least without a large comment explaining it. Although seasoned developers may be able to work it out, those less experienced may have trouble.
And, in fact, even seasoned developers shouldn't have to work it out, especially given it took me a few minutes.
C++ has a very expressive type system which can easily build something like this up in parts, so you don't have to experience migraines trying to work it out. For something like this, I'd be using std::vector
(or std::array
) unless there was a compelling case for the added complexity caused by more basic types.