Реализация оператора <в C ++ - PullRequest
13 голосов
/ 09 июня 2010

У меня есть класс с несколькими числовыми полями, такими как:

class Class1 {
    int a;
    int b;
    int c;
public:
    // constructor and so on...
    bool operator<(const Class1& other) const;
};

Мне нужно использовать объекты этого класса в качестве ключа в std::map.Поэтому я реализую operator<.Какую простую реализацию operator< использовать здесь?

РЕДАКТИРОВАТЬ: Можно предположить значение <, чтобы гарантировать уникальность при условии, что любое из полей неравны.

РЕДАКТИРОВАТЬ 2:

Упрощенная реализация:

bool Class1::operator<(const Class1& other) const {
    if(a < other.a) return true;
    if(a > other.a) return false;

    if(b < other.b) return true;
    if(b > other.b) return false;

    if(c < other.c) return true;
    if(c > other.c) return false;

    return false;
}

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

Ответы [ 5 ]

34 голосов
/ 09 июня 2010

Полагаю, вы хотите реализовать лексикографическое упорядочение.

До C ++ 11:

#include <boost/tuple/tuple.hpp>
#include <boost/tuple/tuple_comparison.hpp>
bool Class1::operator<(const Class1& other) const
{
    return boost::tie(a, b, c) < boost::tie(other.a, other.b, other.c);
}

Начиная с C ++ 11:

#include <tuple>
bool Class1::operator<(const Class1& other) const
{
    return std::tie(a, b, c) < std::tie(other.a, other.b, other.c);
}
15 голосов
/ 09 июня 2010

Я думаю, что есть недопонимание того, что требует map.

map не требует от вашего класса определения operator<. Требуется передать подходящий предикат сравнения, который по умолчанию имеет значение std::less<Key>, которое использует operator< для Key.

Вы не должны использовать operator<, чтобы соответствовать ключу в map. Вы должны реализовать его, только если вы определите его для этого класса: т.е. если он имеет смысл.

Вы можете прекрасно определить предикат:

struct Compare: std::binary_function<Key,Key,bool>
{
  bool operator()(const Key& lhs, const Key& rhs) const { ... }
};

А потом:

typedef std::map<Key,Value,Compare> my_map_t;
4 голосов
/ 09 июня 2010

Зависит от того, насколько важен для вас порядок заказа.Если нет, вы можете просто сделать это:

bool operator<(const Class1& other) const
{
    if(a == other.a)
    {
         if(b == other.b)
         {
             return c < other.c;
         }
         else
         {
             return b < other.b;
         }
    }
    else
    {
        return a < other.a;
    }
}
0 голосов
/ 19 мая 2018

Версия, которая позволяет избежать многократного отступа:

bool operator<(const Class1& other) const
{
    if(a != other.a)
    {
        return a < other.a;
    }

    if(b != other.b)
    {
        return b < other.b;
    }

    return c < other.c;
}

Авторская версия "Edit 2" имеет в среднем больше сравнений, чем это решение. (от худшего случая 6 до худшего случая 3)

0 голосов
/ 09 июня 2010

Вы можете сделать:

return memcmp (this, &other, sizeof *this) < 0;

но у этого довольно много предостережений - например, нет vtbl и еще много, я уверен.

...