The function returns a reference to an int array of size 3 and [3] after the function, in fact the size of the array to be returned as a link.
This obscure syntax comes from the weird array declaration syntax that you do as:
int arr[3];
The language would be much simpler if it had this:
int[3] arr;
because size 3 is part of type arr , so it makes sense if all parts appear on the left side of the variable name in the same way as when writing:
unsigned int a;
You are not writing:
unsigned a int;
So, when the language does the right thing with unsigned int , it is very strange with int[3] .
Now, returning to the declaration of the function, the function would be much better if it were declared as:
int[3]& f(int[3]& arr);
only if it had all the parts on the left side of the variable name. But since it does not (that is, the language requires you to write the size on the right side after the variable name), you get into this strange signature:
int (&f(int (&arr)[3])[3];
Note that even the parameter becomes weird.
But you can simplify it with typedef like:
typedef int array_type[3]; array_type& f(array_type& arr);
It looks a lot better. Now only typedef looks weird.
With C ++ 11 you can write even the best typedef:
using array_type = int[3]; array_type& f(array_type& arr);
which is close to this (if you render array_type as int[3] ):
int[3]& f(int[3]& arr);
Hope this helps.