35

We can pass reference of an array to a function like:

void f(int (&a)[5]);

int x[5];
f(x);     //okay
int y[6];
f(y);     //error - type of y is not `int (&)[5]`.

Or even better, we can write a function template:

template<size_t N>
void f(int (&a)[N]); //N is size of the array!

int x[5];
f(x);     //okay - N becomes 5
int y[6];
f(y);     //okay - N becomes 6

Now my question is, how to return reference of an array from a function?

I want to return array of folllowing types from a function:

int a[N];
int a[M][N];
int (*a)[N];
int (*a)[M][N];

where M and N is known at compile time!

What are general rules for passing and returning compile-time reference of an array to and from a function? How can we pass reference of an array of type int (*a)[M][N] to a function?

EDIT:

Adam commented : int (*a)[N] is not an array, it's a pointer to an array.

Yes. But one dimension is known at compile time! How can we pass this information which is known at compile time, to a function?

6
  • 1
    int (*a)[N] is not an array, it's a pointer to an array. Commented Mar 22, 2011 at 23:06
  • 1
    @Adam: Yes. But one dimension is known at compile time! Commented Mar 22, 2011 at 23:08
  • 3
    @ThomasMatthews I know this is comment necromancy but that's a terrible suggestion. If he were to use an stl container to replace a compile time known bounds array he would use std::array not std::vector. Commented May 14, 2014 at 5:43
  • 3
    @CoffeeandCode: You may not have noticed that the date of the post is 2011, and C++11 may not have been available. The std::array is a C++11 feature. Commented May 14, 2014 at 13:39
  • 2
    @ThomasMatthews even so, you shouldn't replace a statically sized array with a dynamically resized array if you need compile-time size Commented May 14, 2014 at 22:07

5 Answers 5

47

If you want to return a reference to an array from a function, the declaration would look like this:

// an array
int global[10];

// function returning a reference to an array
int (&f())[10] {
   return global;
}

The declaration of a function returning a reference to an array looks the same as the declaration of a variable that is a reference to an array - only that the function name is followed by (), which may contain parameter declarations:

int (&variable)[1][2];
int (&functionA())[1][2];
int (&functionB(int param))[1][2];

Such declarations can be made much clearer by using a typedef:

typedef int array_t[10];

array_t& f() {
   return global;
}

If you want it to get really confusing, you can declare a function that takes a reference to an array and also returns such a reference:

template<int N, int M>
int (&f(int (&param)[M][N]))[M][N] {
   return param;
}

Pointers to arrays work the same, only that they use * instead of &.

Sign up to request clarification or add additional context in comments.

5 Comments

+1. Great. I wanted something like this. Now please pass and return other types as well. My question has several types. Also explain the rules!
The last example is used in a common snippet to obtain the size of an array as a static constant: template <typename T, int N> char (&size_detail( T (&)[N] ))[N]; #define sizeof_array( a ) sizeof( size_detail(a) )
Also: noexcept and const (for methods) still goes after the argments. E.g. const noexept method foo that returns a reference to an int array of size 10 and takes a single char argument is declared as int (&foo(char) const noexcept)[10];. At that point, its probably better to use typedefs or trailing returns.
How do we specify such a function is a const member function?
@Ayxan: See Artyer's comment
12

With C++11's trailing return type syntax, you can also write:

auto foo () -> int (&)[3]
{
    static int some_array[3]; // doesn't have to be declared here
    return some_array; // return a reference to the array.
}

2 Comments

Which returns a reference to an int array of three elements.
Ooh wow this is a really neat feature. ibm.com/developerworks/community/blogs/…
9

You cannot return an array from a function.

8.3.5/6:

Functions shall not have a return type of type array or function, although they may have a return type of type pointer or reference to such things.

EDIT: You'll love the syntax:

int (&bar()) [5] {
  static int x[5];
  return x;
}


int (* & bar()) [6][10] {
    static int x[6][10];
    static int (*y)[6][10] = &x;
    return y;
}
// Note - this returns a reference to a pointer to a 2d array, not exactly what you wanted.

2 Comments

Erik, I made it reference in my question. Now please answer!
@Nawaz: Have fun. Now please typedef this makes my head hurt :P
3

As Erik mentioned, you can't return an array from a function. You can return a pointer or a reference, although the syntax is quite hairy:

// foo returns a pointer to an array 10 of int
int (*foo(float arg1, char arg2))[10] { ... }

// bar returns a reference to an array 10 of int
int (&foo(float arg1, char arg2))[10] { ... }

I'd strongly recommend making a typedef for the array type:

// IntArray10 is an alias for "array 10 of int"
typedef int IntArray10[10];

// Equivalent to the preceding definitions
IntArray10 *foo(float arg1, char arg2) { ... }
IntArray10 &bar(float arg1, char arg2) { ... }

Comments

0

This is tagged C++, so I'm going to suggest that the way to return an array in C++ is to return a std::vector and not try any trickery with C-arrays (which should be used only in carefully selected scenarios in C++ code).

As other answers noted, you can't return C-arrays from functions.

1 Comment

That is if you're fine with 16 bytes of overhead every time you pass it around.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.