Syntax for returning an array reference in C ++

I studied the concepts of an array in C ++ when I came across this question: Return an array in C ++

Someone answered using this ad:

int (&f(int (&arr)[3]))[3] 

What I canโ€™t understand is [3] after closing in brackets. I have never seen a function declaration that looked like this. I understand the rest of the syntax, but I donโ€™t really understand how it works [3], because it is after the function name. I apologize in advance if I miss something simple. I also tried to look at the specification for function declarations, but I did not see anything related to the fact that I could refer to the index syntax. So how is this possible?

+7
c ++ function arrays reference declaration
source share
3 answers

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]; //real but weird 

The language would be much simpler if it had this:

 int[3] arr; //hypothetical but better and simpler 

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; //analogous to : int a [3]; 

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); //hypothetical 

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]; //real 

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); //hypothetical 

Hope this helps.

+5
source share

Well, read this article about the story of C, by its creator Dennis M. Ritchie.

Looks like this syntax we got from B, through C to C ++ ...

I believe this way of declaring several variables of some โ€œbase typeโ€ is the root of this strange syntax:

 int a, *b, c[3]; 

So a is just int , b is a pointer to int and c is an array of int ...

If these * and [3] are part of the type definition of a non-variable definition, then we need 3 lines to write this:

 int a; int* b; int[3] c; 

There are two good resources on the SO C page to learn how to parse such constructs:

cdecl doesnโ€™t work a bit - because links are not part of C, so try the Rule clockwise / helix to parse C declarations.

 int (&f(int (&arr)[3]))[3] 
  • arr โ†’ arr
  • &arr โ†’ arr is a link
  • (&arr) โ†’ arr - link - ambient () does not change anything.
  • (&arr)[3] โ†’ arr refers to an array of size 3
  • int (&arr)[3] โ†’ arr refers to an array of size 3 of type int

Further:

  • f โ†’ f
  • f(int (&arr)[3]) โ†’ f is a function that takes arr, which ...
  • &f(int (&arr)[3]) โ†’ f is a function that takes arr, which is ... and returns a link
  • (&f(int (&arr)[3]))[3] โ†’ f is a function that takes arr, which is ... and returns a reference to an array of size 3
  • int (&f(int (&arr)[3]))[3] โ†’ f is a function that takes arr, which refers to an array of size 3 of type int and returns a link to an array of size 3 of type int

Of course - this code should be replaced, at least for me, it is much easier to read the version:

 using int3 = int[3]; int3& f(int3& arr); 
+2
source share
 int (&f (int (&arr)[3]) )[3] { return arr; } 

Release from the inside. Part (int (&arr)[3]) means that the function takes a reference to an int array of 3 elements as a parameter. This is the same arr that returns.

Now the rest of the saiys syntax should return a reference to an array of 3 integers. f is the name of the function. int &f() means that you will return a reference to int , but you need to return an array of a fixed size, so you must add [3] . The braces around &f(...) are used because in C ++ you write the size of the array after the variable name and not after the type name, as Nawaz explains in his answer. If you omit these brackets, the compiler interprets f as an array of links, as in int & f[3] .

+1
source share

All Articles