Разработка объекта в C ++, который можно сравнивать несколькими способами - PullRequest
2 голосов
/ 18 марта 2012

Предположим, у нас есть объект, представляющий блок.

class Box {
  public:
    int length;
    int width;
    int height;

    Box(int l, int w, int h);
    ~Box();
    int area(const int l, const int w) const;
    int volume(const int l, const int w, const int h) const; 
};

Теперь давайте скажем, что в другом классе, в другом файле, у нас есть std::list<Box>, который содержит n блоков.Мы хотим отображать распечатки из этих полей по-разному.

  • Сначала мы хотим распечатать их в порядке увеличения размера по длине.
  • Затем мы хотим распечатать их в порядке увеличения размера по их ширине.
  • Сейчас нас не волнует их высота, но, может быть, позже мы это сделаем.

Теперь std::list имеет функцию-член sort(), которая принимает функцию сравнения в качествеаргумент.Как мы можем изменить вышеупомянутый класс Box, чтобы мы могли вызывать sort() в нашем списке с различными функциями сравнения?

В частности, можем ли мы определить три различные функции внутри класса box и просто передать их list.sort()?Лучше ли определять функции сравнения глобально вне класса, интуитивно, связывая их с классом, кажется лучше, но почему бы это не так?В целом, каков «лучший» способ добиться этого?

Ответы [ 6 ]

3 голосов
/ 18 марта 2012

Если вы действительно хотите реализовать три разных сравнения операции в качестве членов вы можете сделать что-то вроде этого:

struct Box {
  int x, y, length;

  bool less_by_x(const Box& other) { return this.x < other.x; }
  bool less_by_y(const Box& other) { return this.y < other.y; }
  bool less_by_length(const Box& other) { return this.y < other.y; }
};

и используйте их так:

#include <functional>
// you probably shouldn't be using a list anyway
std::list<Box> l; 
l.sort(std::mem_fun_ref(&Box::less_by_x));

mem_fun_ref возвращает объект двоичной функции, который принимает ссылку на класс, членом которого является функция, и все остальные аргументы (только в C ++ 11, это ограничено двоичными функциями в C ++ 03) функций-членов.

Несмотря на то, что сравнение представляется более разумным, операции как свободные функции.

1 голос
/ 18 марта 2012

Вы должны предоставить функцию компаратора (или функциональный объект). Например:

bool my_sort_function (const Box& box1, const Box& box2)
{
        // use some criteria and return a boolean (true if box1 goes before box2)
        // ...
}

Затем вызовите метод sort () следующим образом:

my_list.sort (my_sort_function);
0 голосов
/ 18 марта 2012

Лучший способ сделать это - реализовать функцию сравнения для каждого параметра и передать ее для сортировки при вызове сортировки. Булево сравнение этой функции (блок a, блок b) должно быть эквивалентно a

0 голосов
/ 18 марта 2012

Различные функции сортировки в стандартной библиотеке C ++ принимают объекты сравнения.Они могут содержать любые данные, которые им нужны.Основные требования, которые у них есть, заключаются в том, что они являются копируемыми и что их оператор вызова функции дает строгий слабый порядок при применении к объектам их типа аргумента.Легко создать объект сравнения, который, например, хранит указатель на функцию-член, используемую для сопоставления объекта с атрибутом, особенно если все атрибуты имеют одинаковый тип (если атрибуты имеют разные типы, вещи немного интереснее).При этом довольно просто отсортировать один и тот же список по разным порядкам.

0 голосов
/ 18 марта 2012

std::list::sort() принимает объект функции сравнения, который позволяет определять пользовательские критерии сортировки.Это может быть обычная функция (свободная функция или статический член) или экземпляр класса с совместимым operator().См. некоторую документацию для подробностей и примера.

0 голосов
/ 18 марта 2012

Если вы хотите передать функции-члены в качестве параметров, тогда лучше всего использовать boost :: mem_fn

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