Я работаю над системой, где я должен смочь отсортировать вектор по данному предикату, которым не должны управлять мои классы. В основном я передаю их производный класс и они вслепую вид на нем.
Как одна из "восхитительных причуд", один из шаблонов вида является порядком записи. Вот то, что я имею до сих пор.
struct Strategy
{
virtual bool operator()(const Loan& lhs, const Loan& rhs) const = 0;
};
struct strategyA : public Strategy
{
bool operator()(const Loan& lhs, const Loan& rhs) const
{
return true;
}
};
struct strategyB : public Strategy
{
bool operator()(const Loan& lhs, const Loan& rhs) const
{
return lhs.getID() > rhs.getID();
}
};
struct strategyC : public Strategy
{
bool operator()(const Loan& lhs, const Loan& rhs) const
{
return lhs.getFee() > rhs.getFee();
}
};
Очевидно, поскольку strategyA рефлексивен, он не может использоваться, и если я установил его на ложь, он будет рассматривать все как равное, и я могу поцеловать на прощание со своими данными.
Таким образом, вот мой вопрос. Существует ли способ определить функцию предиката для сортировки вектора, который ничего НЕ изменит?
Я знаю, что возможно простое решение состоит в том, чтобы добавить порядок переменной записи к классу Ссуды, или сотрудничать с ним с одним в паре. Кроме того, я мог подать параметр в с предикатом, который говорит сортировщику, использовать ли его или нет.
Лично я думаю, что ваш класс стратегии должен иметь метод "sort". Таким образом, он может либо вызывать std::sort, либо нет, по своему усмотрению. Ли, как и как, становится частью стратегии сортировки.
Ответ Darios stable_sort очень хорош, если вы можете его использовать.
Можно сделать сортировку на основе позиции элемента в векторе, но это не означает, что элементы не будут перемещаться (многие алгоритмы сортировки будут в основном скремблировать-пересортировывать ваши данные), поэтому у вас должен быть какой-то надежный способ определить, где были элементы, когда вы начали.
Возможно, при сравнении можно сохранить отображение текущей позиции на исходную, но это требует большой работы. В идеале логика должна быть встроена в алгоритм сортировки - не только в сравнение - и именно так работает stable_sort.
Еще одна проблема - в зависимости от контейнера порядок (скажем) адресов элементов не всегда совпадает с порядком элементов.
Есть ли способ определить функцию предиката для сортировки вектора, которая НЕ изменит ничего?
Это зависит от алгоритма. Если ваша сортировка является стабильной сортировкой , порядок «равных» элементов не будет изменен (что не определено для нестабильных сортировок).
Рассмотрите возможность использования std :: stable_sort
.
Если вы говорите просто о векторе, возможно, вам удастся предоставить интерфейс, который определяет, следует ли вам выполнять сортировку или нет. векторы не являются упорядоченным контейнером, поэтому вам необходимо явно отсортировать их. Только не сортируйте их вообще.
Нет функции сортировки, которая сохраняла бы порядок элементов только на основе их значений. Вам необходимо предоставить дополнительную информацию в свою Стратегию
, если это возможно.
Другой подход может заключаться в переносе семантики ваших данных в контейнер. Рассмотрите возможность использования boost :: multi_index для различных способов доступа и упорядочивания одних и тех же данных:
http://www.boost.org/doc/libs/1_42_0/libs/multi_index/doc/index.html