2

Would someone please explain a little about the syntax below ?

void initList_v(Room *(& roomsList_p)[3])
{
  roomsList_p[3] = new Room[3];
}

What is the significance of *(&) in the signature of the function ? This is not a function pointer. Would anyone help me in understand this ?

chinmaya
  • 91
  • 9

3 Answers3

1

To interpret a type of a variable, unwrap it from the inside out:

Room *(& roomsList_p)[3]

  • roomsList_p: roomsList_p is a
  • &: reference to
  • [3]: an array of three
  • *: pointers to
  • Room: Room instances.

Why would someone make a reference to an array when an array decays to a pointer anyway, and the function could be declared like this:

void initList_v(Room *roomsList_p[3])

It is for type safety: precisely because the array decays to a pointer, the declared size of the array parameter is ignored. But when the parameter is declared as a reference, callers are forced to pass arrays of the declared size.


Side note: Since brackets [] bind stronger than pointer * and reference &, parentheses have to be used to disambiguate the reference:

Room *& roomsList_p[3]

would be illegal, because that would have to be interpreted as an array of references to something, but arrays of references are not allowed.

j6t
  • 9,150
  • 1
  • 15
  • 35
0

I don't know how you found this code, however, I wouldn't recommend using it unless you have to. Let's break it down, if you would be writing: Room name[3], it would mean an array to 3 Rooms. It has been extended to Room* name[3] to become an array to 3 pointers to Room. And following that, it has been given reference semantics Room* &name[3]. Unfortunately, this doesn't compile, as it gets interpret to an array of to 3 references to points of Room, hence the parenthesis, which make this:

 Room *(& name)[3]

My recommendation would be to use C++ structures instead of the C ones, by using the standard library <array>.

void initList_v(std::array<Room *, 3> &roomsList_p)
{
    roomsList_p[3] = new Room[3];
}

As it's bad practice to have raw pointers with ownership, this even could become updated:

void initList_v(std::array<std::unique_ptr<Room[]>, 3> &roomsList_p)
{
    roomsList_p[3] = std::make_unique<Room[]>(3);
}

And as returning by output arguments is also bad practice, it makes more sense to actually return.

auto initList_v()
{
    std::array<std::unique_ptr<Room[]>, 3> roomsList_p;
    roomsList_p[3] = std::make_unique<Room[]>(3);
    return roomsList_p;
}

Some final advice: You code contains a bug, as you are indexing out-of-bounds.

JVApen
  • 11,008
  • 5
  • 31
  • 67
-2

&roomsList_p is an array reference (address) and (& roomsList_p)[3] refers to its 3rd element.

Room *(& roomsList_p)[3] mean "(& roomsList_p)[3]" is a pointer of Type Room

( as the name implies, the roomsList_p is an array/list of pointers to type Room )

sarath sg
  • 1
  • 2