M.Naro
M.Naro

Reputation: 77

C++ find_if element in map

I am trying to understand how the find_if function and map container works. I have function in Map.cpp - Tile& Map::getTile(const Point& point) which returns Tile from map container. I should go through the container and check whether current map Tile's Point position == argument of function.

I am not sure about the third parameter of find_if - how can i pass parameter of actual point from map to operator==() and return found Tile? Let me know if I should provide complete .cpp files. Thanks for your time!

Map.cpp

#include "map.h"
#include <iostream>
#include <map>
#include <algorithm>
    Map::Map(int rows, int columns, int mines) {
        this->rows = rows;
        this->columns = columns;
        this->totalMines = mines;
        std::map<Point, Tile> tileContainer = {};
    }


    Tile& Map::getTile(const Point& point) {
        std::map<Point, Tile>::iterator it = std::find_if(tileContainer.begin(), tileContainer.end(), point.operator==(?);

    }

Point.h

#include "interfaces.h"
    struct Point : public APoint {
    private:
        int row;
        int column;
    public:
        Point(int row, int column);
        ~Point();
        int getRow() const;
        int getColumn() const;
        bool isInContact(const Point& point) const;
        bool operator==(const Point& point) const;
        bool operator!=(const Point& point) const;
    };

Tile.h

#include "interfaces.h"
#include "point.h"
    struct Tile : public ATile {
    private:
        Point& position;
        int bombsInNeighbourhood;
        bool bombTile;
        TileState tileState;
    public:
        Tile(const Point& position);
        ~Tile();
        const Point& getPosition();
        void setPosition(const Point& position);
        int getBombsInNeighbourhood() const;
        void setBombsInNeighbourhood(int bombsInNeighbourhood);
        bool isBombTile() const;
        void setBombTile(bool bombTile);
        TileState getTileState() const;
        void setTileState(TileState tileState);
    };

Map.h

#include "interfaces.h" 
#include "point.h"
#include "tile.h"
    struct Map : public AMap {
    protected:
        int rows;
        int columns;
        int totalMines;
        std::map<Point&, Tile> tileContainer;
    public:
        Map(int rows, int columns, int mines);
        ~Map();
        Tile& getTile(const Point& point);
        Tile& getTile(int row, int column);
        const Tile& getTile(const Point& point) const;
        const Tile& getTile(int row, int column) const;

Point.cpp function I use:

bool Point::operator==(const Point& point) const {
    if (point.column == this->getColumn() && point.row == this->getRow()) {
        return true;
    }
    else {
        return false;
    }
}

Upvotes: 1

Views: 8644

Answers (1)

R Sahu
R Sahu

Reputation: 206737

The third argument to std::find_if must be a UnaryPredicate. It takes one argument and returns a bool.

You can use the following for a UnaryPredicate.

  1. A non-member function.
  2. An object that has the function call operator, operator().
  3. A lambda function.

When you are using std::find_if with elements of a std::map, you have to take into account that each item of std::map is a std::pair. From http://en.cppreference.com/w/cpp/container/map,

value_type  std::pair<const Key, T>

Here's one solution to your problem, using a lambda function.

Tile& Map::getTile(const Point& point)
{
   auto it = std::find_if(tileContainer.begin(),
                          tileContainer.end(),
                          [&point](std::pair<Point, Title> const& item)
                          {
                             return (point == item.first);
                          });

   ...
}

However, if you want to compare just the key, you might as well use std::map::find.

Tile& Map::getTile(const Point& point)
{
   auto it = tileContainer.find(point);

   ...
}

Upvotes: 3

Related Questions