Как вставить значения в набор C ++ - PullRequest
0 голосов
/ 09 октября 2011

Я пытаюсь создать набор пользовательских объектов класса Point

point.h

#ifndef POINT_H
#define POINT_H

class Point
{
      float x_coordinate,y_coordinate;
      public:
             Point(float x, float y):x_coordinate(x),y_coordinate(y)
             {}

             float get_x()
             {
                   return x_coordinate;
             }

             float get_y()
             {
                   return y_coordinate;
             }

             bool operator==(Point rhs)
             {
                  if( ((int)x_coordinate == (int)rhs.get_x()) && ((int)y_coordinate == (int)rhs.get_y()) )
                      return true;
                  else return false;
             }

             bool operator<(Point rhs)
             {
                  if((int)x_coordinate < (int)rhs.get_x())
                      return true;
                  else return false;
             }
};

#endif

Я только начал писать драйвер

#include<iostream>
#include<set>
#include "point.h"
using namespace std;



int main()
{
    Point p1(-10,-10),p2(-10,10),p3(10,10),p4(10,-10);
    set<Point> points_set = set<Point>();
    points_set.insert(p1);

    return 0;
}

но я получаю эту ошибку во время компиляции, я перегружен оператором сравнения и равенства, что еще я должен сделать, чтобы заставить его работать?

In file included from /usr/include/c++/4.6/string:50:0,
                 from /usr/include/c++/4.6/bits/locale_classes.h:42,
                 from /usr/include/c++/4.6/bits/ios_base.h:43,
                 from /usr/include/c++/4.6/ios:43,
                 from /usr/include/c++/4.6/ostream:40,
                 from /usr/include/c++/4.6/iostream:40,
                 from driver.cpp:1:
/usr/include/c++/4.6/bits/stl_function.h: In member function ‘bool std::less<_Tp>::operator()(const _Tp&, const _Tp&) const [with _Tp = Point]’:
/usr/include/c++/4.6/bits/stl_tree.h:1267:4:   instantiated from ‘std::pair<std::_Rb_tree_iterator<_Val>, bool> std::_Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::_M_insert_unique(const _Val&) [with _Key = Point, _Val = Point, _KeyOfValue = std::_Identity<Point>, _Compare = std::less<Point>, _Alloc = std::allocator<Point>]’
/usr/include/c++/4.6/bits/stl_set.h:410:29:   instantiated from ‘std::pair<typename std::_Rb_tree<_Key, _Key, std::_Identity<_Key>, _Compare, typename _Alloc::rebind<_Key>::other>::const_iterator, bool> std::set<_Key, _Compare, _Alloc>::insert(const value_type&) [with _Key = Point, _Compare = std::less<Point>, _Alloc = std::allocator<Point>, typename std::_Rb_tree<_Key, _Key, std::_Identity<_Key>, _Compare, typename _Alloc::rebind<_Key>::other>::const_iterator = std::_Rb_tree_const_iterator<Point>, std::set<_Key, _Compare, _Alloc>::value_type = Point]’
driver.cpp:12:25:   instantiated from here
/usr/include/c++/4.6/bits/stl_function.h:236:22: error: passing ‘const Point’ as ‘this’ argument of ‘bool Point::operator<(Point)’ discards qualifiers [-fpermissive]

Ответы [ 6 ]

6 голосов
/ 09 октября 2011
float get_x() const { ... }
float get_y() const { ... }
bool operator==(Point const& rhs) const { ... }
bool operator<(Point const& rhs) const { ... }

Вам не хватает всех этих const s, в аргументах и ​​для самих методов.

Примечание. Я не уверен, какие требования предъявляются к operator< для элементов в set, но тот, который вы предоставляете, очень слабый.

2 голосов
/ 09 октября 2011

@ Мат побей меня до этого , чтобы ответить на твой конкретный вопрос. Поэтому я просто укажу на проблему с вашим неидиоматическим C ++. Вам не нужно условие для возврата логического значения. Просто верните значение того, что было бы вашим if утверждением:

bool operator==(const Point& rhs) const
{
    return ((int)x_coordinate == (int)rhs.get_x()) && ((int)y_coordinate == (int)rhs.get_y());
}

bool operator<(const Point& rhs) const
{
    return (int)x_coordinate < (int)rhs.get_x();
}

Кроме того, лучше указать механизм явного приведения в C ++, чем использовать случай в стиле C:

    return static_cast<int>(x_coordinate) < static_cast<int>(rhs.get_x());
2 голосов
/ 09 октября 2011

Вы должны объявить operator == и operator <как постоянные функции-члены. Это позволит им вызываться для константных объектов, как и все объекты, хранящиеся в наборе: </p>

bool operator<(Point rhs) const

Как уже отмечали другие, с вашим примером кода есть и другие проблемы:

  • get_x и get_y также должны быть константными методами
  • Ваша реализация оператора <слишком слабая в сравнении. std :: set использует понятие "эквивалентности" при выполнении вставок и поисков. Тот факт, что несколько различных объектов могут не согласовываться согласованно с оператором <(т.е. это не «слабая функция упорядочения»), определенно будет связан с другими операциями std :: set. В частности, в вашем примере кода набор не может различить (-10, -10) и (-10, 10). Вы должны хотя бы сравнить точки для координат x и y и использовать сравнение с плавающей точкой вместо целочисленного сравнения </li>
1 голос
/ 09 октября 2011

Другие затронули проблему const. Я хочу добавить, что когда вы объявляете свой points_set, вы можете просто сказать:

set<Point> points_set;

вместо того, что у вас есть сейчас:

set<Point> points_set = set<Point>();
1 голос
/ 09 октября 2011

Правильная подпись:

bool operator<(const Point & rhs) const

, кроме того, вам необходимо объявить const функцию get_x и get_y

operator= имеет аналогичную подпись, нов этом случае это не обязательно.

0 голосов
/ 09 октября 2011

Вам необходимо передать Point как const & обоим операторам.Сами операторы тоже должны быть константными.

Я также заметил, что оператор <не сравнивает координату y, это намеренно?Учтите, что (0/7) <(0/5) будет ложным, а (0/5) <(0/7) также ложным. </p>

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...