Error when trying to pass '==' overload to std::map comparator

60 views Asked by At

I'm trying to pass an overload of a custom class as a comparator of an std::map.

Here's some code and the error to help you help me :

Here is Position.hpp

#ifndef POSITION_HPP_
# define POSITION_HPP_

class   Position
{
public:
  int   _x;
  int   _y;

  Position(){}
  Position(int x, int y)
  {
    _x = x;
    _y = y;
  }

  void  setPosition(Position &newpos)
  {
    _x = newpos._x;
    _y = newpos._y;
  }

  int   getX()
  {
    return _x;
  }

  int   getY()

     return _y;
  }
  void  setX(int x)
  {
    _x = x;
  }
  void  setY(int y)
  {
    _y = y;
  }

  struct cmpIsSame{
    inline bool operator==(const Position& pos)
    {
      if (pos._x == _x && pos._y == _y)
        return true;
      return false;
    }
  };

  inline Position&      operator=(const Position& pos)
  {
    _x = pos._x;
    _y = pos._y;
    return *this;
  }
};

#endif

And here is the map declaration in GameEngine.hh

private:
  std::map<Position, Case, Position::cmpIsSame> _cases;

And here is the error:

Position.hpp: In member function ‘bool Position::cmpIsSame::operator==(const Position&)’:
Position.hpp:17:7: error: invalid use of non-static data member ‘Position::_x’
   int _x;
       ^
Position.hpp:52:21: error: from this location
       if (pos._x == _x && pos._y == _y)
                     ^
Position.hpp:18:7: error: invalid use of non-static data member ‘Position::_y’
   int _y;
       ^
Position.hpp:52:37: error: from this location
       if (pos._x == _x && pos._y == _y)
                                     ^

Any help would be a pleasure?

2

There are 2 answers

0
Niall On BEST ANSWER

As to the error

In the implementation of the operator== you attempt to access members _x etc. of the enclosing class. You don't have access to them there. Embedding a class in a class is a namespace issue, not a member access issue.

It would be easier to just provide a free function or a functor that offers the comparison.

As to the comparison of keys in map

The definition of the key comparison for std::map is std::less which by default calls operator<. It may be easier to just implement an overloaded operator< for the key you use.

bool operator<(const Position& lhs, const Position rhs&) {
  // your implementation of "less" here...
}

As to the implementation of less

This is really up to you and manner in which you use it in the application. But as a first off approximation (also to try get the code up and going), consider using the distance (pythagorean theory) of the point to the origin (probably 0,0).

0
Vlad from Moscow On

First of all you have to use either functional object or a static function. But in any case your approach is wrong because the comparator shall satisfy the strict weak ordering principle that correcponds to operator <.

From the C++ Standard (23.2.4 Associative containers)

3 The phrase “equivalence of keys” means the equivalence relation imposed by the comparison and not the operator== on keys. That is, two keys k1 and k2 are considered to be equivalent if for the comparison object comp, comp(k1, k2) == false && comp(k2, k1) == false. For any two keys k1 and k2 in the same container, calling comp(k1, k2) shall always return the same value.