Home > other >  how to check if unique_ptr points to this
how to check if unique_ptr points to this

Time:10-14

In following peace of code, I'm trying to find another object that has the same coordinates as this. How to do it correctly?

        auto& organism_vector = world->get_vector();
        auto attacked_organism = find_if(begin(organism_vector), end(organism_vector), [this](const unique_ptr<Organism>& attacked_organism)
            {
                return this->get_coordinates() == attacked_organism->get_coordinates() && *this != *attacked_organism;
            });

Another thing, when I finally manage to get this iterator, how to refer to attacked_organism class methods?

*attacked_organism.get_coordinates();

CodePudding user response:

Change *this != *attacked_organism to this != attacked_organism.get():

auto& organism_vector = world->get_vector();
auto attacked_organism = find_if(begin(organism_vector), end(organism_vector),
    [this](const unique_ptr<Organism>& attacked_organism)
    {
        return this->get_coordinates() == attacked_organism->get_coordinates() && this != attacked_organism.get();
    }
);

Once you have the iterator that find_if() returns (and after you validate that it is not the end iterator), you can call methods on the Organism by first dereferencing the iterator to access the unique_ptr that is holding the Organism* pointer, and then dereferencing the unique_ptr to access the Organism itself:

auto attacked_organism = find_if(...);
if (attacked_organism != end(organism_vector))
{
    (**attacked_organism).get_coordinates();
    or:
    (*attacked_organism)->get_coordinates();
    ...
}

On a side note: I would not recommend giving your iterator variable the same name as the lambda parameter. That just makes things confusing to read. The lambda is trying to find an Organism to attack, but it hasn't actually been attacked yet, so you should name the lambda parameter more appropriately, eg:

auto attacked_organism = find_if(begin(organism_vector), end(organism_vector),
    [this](const unique_ptr<Organism>& candidate_organism)
    {
        return this->get_coordinates() == candidate_organism->get_coordinates() && this != candidate_organism.get();
    }
);

For that matter, I wouldn't really suggest naming the iterator as attacked_organism, either. It is not the actual Organism, it is an iterator to the Organism, so something more like this would be more readable:

auto& organism_vector = world->get_vector();
auto found_iterator = find_if(begin(organism_vector), end(organism_vector),
    [this](const unique_ptr<Organism>& candidate_organism)
    {
        return this->get_coordinates() == candidate_organism->get_coordinates() && this != candidate_organism.get();
    }
);
if (found_iterator != end(organism_vector))
{
    auto &attacked_organism = *found_iterator;
    attacked_organism->get_coordinates();
    ...
}
  • Related