bquenin
bquenin

Reputation: 1520

Getting a reference to an item of an array of unique_ptr<>?

I have the following

class Panel {
public:
  std::array<std::array<std::unique_ptr<fb::Block>, Panel::Y>, Panel::X> blocks;
};

And i have a member function like this:

void Panel::processMove() {
  if (move == nullptr) {
    return;
  }
  MoveType type = move->type;
  switch (type) {
    case MoveType::BLOCK_SWITCH: {
      std::unique_ptr<fb::Block> src = blocks[cursor.x][cursor.y];
      std::unique_ptr<fb::Block> dst = blocks[cursor.x + 1][cursor.y];

      if ((src == nullptr) && (dst == nullptr)) {
        break;
      }
      ...
    }
  }

I don't know how to get a temporary reference to the pointed item because this code fails to compile with the following error:

call to implicitly-deleted copy constructor of 'std::unique_ptr<fb::Block>'

How am i supposed to get a temporary reference to the pointed item ?

Upvotes: 0

Views: 591

Answers (2)

Collin
Collin

Reputation: 12287

Just get it as a reference:

std::unique_ptr<fb::Block>& src = blocks[cursor.x][cursor.y]
std::unique_ptr<fb::Block>& dst = blocks[cursor.x + 1][cursor.y]

In fact, since you're using C++11, you can shorten this quite a bit using auto

auto& src = blocks[cursor.x][cursor.y]
auto& dst = blocks[cursor.x + 1][cursor.y]

Or, if you know that all the unique pointers hold a pointer to a valid object, you can get a reference to the object itself, going around the pointer entirely (thanks @ChrisHartman)

fb::Block& src = *(blocks[cursor.x][cursor.y]);
fb::Block& dst = *(blocks[cursor.x + 1][cursor.y]);

//C++11 auto:
auto& src = *(blocks[cursor.x][cursor.y])
auto& dst = *(blocks[cursor.x + 1][cursor.y])

Upvotes: 2

Drew Dormann
Drew Dormann

Reputation: 63830

std::unique_ptr can be evaluated as a bool to check if it points to an object.

Change this:

  std::unique_ptr<fb::Block> src = blocks[cursor.x][cursor.y];
  std::unique_ptr<fb::Block> dst = blocks[cursor.x + 1][cursor.y];

  if ((src == nullptr) && (dst == nullptr)) {
    break;
  }

to this:

  std::unique_ptr<fb::Block> &src = blocks[cursor.x][cursor.y];
  std::unique_ptr<fb::Block> &dst = blocks[cursor.x + 1][cursor.y];

  if ( !src && !dst )) {
    break;
  }

Upvotes: 0

Related Questions