user633658
user633658

Reputation: 2623

Returning an array ... rather a reference or pointer to an array

I am a bit confused. There are two ways to return an array from a method. The first suggests the following:

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

However, how do I capture the return which is an int (*)[]?

Another way is through a reference or pointer:

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

or

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

The return types are either int (*)[] or int (&)[].

The trouble I am having is how I can assign a variable to accept the point and I continue to get errors such as:

can't convert int* to int (*)[]

Any idea what I am doing wrong or what is lacking in my knowledge?

Upvotes: 2

Views: 1560

Answers (3)

Yves
Yves

Reputation: 12371

using arrT10 = int[10]; // Or you can use typedef if you want

arrT10 * func(int i)
{
    arrT10 a10;
    return &a10;

    // int a[10];
    // return a;    // ERROR: can't convert int* to int (*)[]
}

This will give you a warning because func returns an address of a local variable so we should NEVER code like this but I'm sure this code can help you.

Upvotes: 0

Cheers and hth. - Alf
Cheers and hth. - Alf

Reputation: 145239

First, the information you give is incorrect.

You write,

“There are two ways to return an array from a method”

and then you give as examples of the ways

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

and

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

(I’ve added the missing right parenthesis), where you say that this latter way, in contrast to the first, is an example of

“through a reference or pointer”

Well, these two declarations mean exactly the same, to wit:

typedef int A[10];
A* fp1( int i ) { return 0; }

int (*fp2( int i ))[10] { return 0; }

int main()
{
    int (*p1)[10]   = fp1( 100 );
    int (*p2)[10]   = fp2( 200 );
}

In both cases a pointer to the array is returned, and this pointer is typed as "pointer to array". Dereferencing that pointer yields the array itself, which decays to a pointer to itself again, but now typed as "pointer to item". It’s a pointer to the first item of the array. At the machine code level these two pointers are, in practice, exactly the same. Coming from a Pascal background that confused me for a long time, but the upshot is, since it’s generally impractical to carry the array size along in the type (which precludes dealing with arrays of different runtime sizes), most array handling code deals with the pointer-to-first-item instead of the pointer-to-the-whole-array.

I.e., normally such a low level C language like function would be declared as just

int* func()

return a pointer to the first item of an array of size established at run time.

Now, if you want to return an array by value then you have two choices:

  • Returning a fixed size array by value: put it in a struct.
    The standard already provides a templated class that does this, std::array.

  • Returning a variable size array by value: use a class that deals with copying.
    The standard already provides a templated class that does this, std::vector.

For example,

#include <vector>
using namespace std;

vector<int> foo() { return vector<int>( 10 ); }

int main()
{
    vector<int> const   v = foo();
    // ...
}

This is the most general. Using std::array is more of an optimization for special cases. As a beginner, keep in mind Donald Knuth’s advice: “Premature optimization is the root of all evil.” I.e., just use std::vector unless there is a really really good reason to use std::array.

Upvotes: 1

Ben Voigt
Ben Voigt

Reputation: 283624

If you want to return an array by value, put it in a structure.

The Standard committee already did that, and thus you can use std::array<int,10>.

std::array<int,10> func(int i);
std::array<int,10> x = func(77);

This makes it very straightforward to return by reference also:

std::array<int,10>& func2(int i);
std::array<int,10>& y = func2(5);

Upvotes: 9

Related Questions