0

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 ?

2 Answers 2

2

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])
Sign up to request clarification or add additional context in comments.

5 Comments

Or you might just want a reference to the item itself, in which case something like fb::Block& srcBlock = *(blocks[cursor.x][cursor.y]); or just auto& srcBlock = *(blocks[cursor.x][cursor.y]); would be appropriate.
How a reference to the object itself would work since the object can be null and I thought references couldn't be null ?
Seems you have some confusion between pointers and references. The pointer could be null. Then you can't derefence it, in which case the reference to object solution will cause undefined behavior (ie. crash) at run time. But you may know that none of the pointers are null, in which case they always point at an object, and the latter solution would work.
Ok, thanks for the clarification. I suspected something like a crash without this predicate. Actually I don't know if the pointers are null or not. So I guess the first solution best suits my needs.
@bquenin your comment is valid. Trying to get a reference to the object itself will throw an exception when the pointer doesn't own an object.
0

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;
  }

2 Comments

I tried, but I have another compilation error now: non-const lvalue reference to type 'std::unique_ptr<fb::Block>' cannot bind to a value of unrelated type 'fb::Block'
This isn't the place for going through all your errors one at a time. Find yourself a chatroom or a real-world mentor!

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.