2

Hi I am having trouble with this code here from a tutorial about returning Arrays from functions

std::string(&func(std::string(&arr)[10]))[10]
{
    return arr;
}

int main()
{
   std::string array[10] = { "efwefwef","wefffj","mfls","hrkr","sgte","ege","ky","retg","sujtre","fl;yiu" };

   std::string* array23 = func(array);
   std::cout << array23[0] << std::endl; // why does this work
   std::cout << array23[1] << std::endl; // why does this work
}

It compiles fine but I am confused as to how std::string* array23 can be used with the index operator.

I initially thought that this was because std::string was an array of characters and you could access them individually with the index operator but this next code works and I can not figure out why.

::std::uintptr_t x = 2453;
::std::uintptr_t* pX = &x;
std::cout << "Var: " << pX[0]; // pX prints 2453
2
  • In absence of operator overloading, a[b] is equivalent to *(a+b). Also I'm not sure what func is for, you could write std::string *array32 = array; directly. And if a tutorial uses convoluted declarations like std::string(&func(std::string(&arr)[10]))[10] for any purpose other than teaching you how to read them, it's probably not the best tutorial. Commented Aug 29, 2020 at 10:25
  • I have no idea what this code does; that declaration is far too complicated for pretty much anyone to read. Use typedef to create names for intermediate types and use those. Commented Aug 29, 2020 at 14:54

1 Answer 1

2

The plane arrays(c-style) can be decayed to a pointer to the type of the array, and the pointee can be accessed using operator[] (i.e pointer[index]).


The function func returns the reference to an (c-style) array of std::strings with 10 elements in it.

If you write the function clearly with an alias, it would look like:

// alias type: the returned type!
using Type = std::string(&)[10];

Type func(std::string (&arr)[10])
{
    return arr;
}

The std::string(&)[10] array elements can be accessed like normal c-style array via operator[]. So the question is why the code you showed works (i.e. std::string* array23)?

This because of the reason mentioned above. In the case of

std::string* array23 = func(array);

The returned (c-style) array(i.e. from func(array);) is decay to the pointer pointing to the first element of the array.

Meaning

array23[0]

is equivalent to

*(array23 + 0)

and hence it works! The same applies to array23[1] (i.e. equalent to *(array23 + 1)).


If you write the actual type instead there, you need

std::string (&array23)[10] = func(array);
// or
// Type array23 = func(array);
Sign up to request clarification or add additional context in comments.

2 Comments

"func returns the reference to an array ... meaning ... std::string* array23 ... is equivalent to ... std::string (&array23)[10] ... therefore ... operator[] ... works" I feel this is very very misleading. The two are not equivalent. And [] working has nothing to do with func returning a reference.
@HolyBlackCat Yes, realized after wrote the answer. Updated the answer as per. Thanks for pointing out. It should be clear now.

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.