6.3.3. Returning a Pointer to an Array

Because we cannot copy an array, a function cannot return an array. However, a function can return a pointer or a reference to an array (§ 3.5.1, p. 114). Unfortunately, the syntax used to define functions that return pointers or references to arrays can be intimidating. Fortunately, there are ways to simplify such declarations. The most straightforward way is to use a type alias (§ 2.5.1, p. 67):

typedef int arrT[10];  // arrT is a synonym for the type array of ten ints
using arrT = int[10];  // equivalent declaration of arrT; see § 2.5.1 (p. 68)
arrT* func(int i);     // func returns a pointer to an array of ten ints

Here arrT is a synonym for an array of ten ints. Because we cannot return an array, we define the return type as a pointer to this type. Thus, func is a function that takes a single int argument and returns a pointer to an array of ten ints.

Declaring a Function That Returns a Pointer to an Array

To declare func without using a type alias, we must remember that the dimension of an array follows the name being defined:

int arr[10];          // arr is an array of ten ints
int *p1[10];          // p1 is an array of ten pointers
int (*p2)[10] = &arr; // p2 points to an array of ten ints

As with these declarations, if we want to define a function that returns a pointer to an array, the dimension must follow the function’s name. However, a function includes a parameter list, which also follows the name. The parameter list precedes the dimension. Hence, the form of a function that returns a pointer to an array is:

Type (*function(parameter_list))[dimension]

As in any other array declaration, Type is the type of the elements and dimension is the size of the array. The parentheses around (*function (parameter_list)) are necessary for the same reason that they were required when we defined p2. Without them, we would be defining a function that returns an array of pointers.

As a concrete example, the following declares func without using a type alias:

int (*func(int i))[10];

To understand this declaration, it can be helpful to think about it as follows:

func(int) says that we can call func with an int argument.

(*func(int)) says we can dereference the result of that call.

(*func(int))[10] says that dereferencing the result of a call to func yields an array of size ten.

int (*func(int))[10] says the element type in that array is int.

Using a Trailing Return Type
Image

Under the new standard, another way to simplify the declaration of func is by using a trailing return type. Trailing returns can be defined for any function, but are most useful for functions with complicated return types, such as pointers (or references) to arrays. A trailing return type follows the parameter list and is preceded by ->. To signal that the return follows the parameter list, we use auto where the return type ordinarily appears:

// fcn takes an int argument and returns a pointer to an array of ten ints
auto func(int i) -> int(*)[10];

Because the return type comes after the parameter list, it is easier to see that func returns a pointer and that that pointer points to an array of ten ints.

Using decltype

As another alternative, if we know the array(s) to which our function can return a pointer, we can use decltype to declare the return type. For example, the following function returns a pointer to one of two arrays, depending on the value of its parameter:

int odd[] = {1,3,5,7,9};
int even[] = {0,2,4,6,8};
// returns a pointer to an array of five int elements
decltype(odd) *arrPtr(int i)
{
    return (i % 2) ? &odd : &even; // returns a pointer to the array
}

The return type for arrPtr uses decltype to say that the function returns a pointer to whatever type odd has. That object is an array, so arrPtr returns a pointer to an array of five ints. The only tricky part is that we must remember that decltype does not automatically convert an array to its corresponding pointer type. The type returned by decltype is an array type, to which we must add a * to indicate that arrPtr returns a pointer.


Exercises Section 6.3.3

Exercise 6.36: Write the declaration for a function that returns a reference to an array of ten strings, without using either a trailing return, decltype, or a type alias.

Exercise 6.37: Write three additional declarations for the function in the previous exercise. One should use a type alias, one should use a trailing return, and the third should use decltype. Which form do you prefer and why?

Exercise 6.38: Revise the arrPtr function on to return a reference to the array.


..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
52.15.74.25