Требование компаратора для equal_range - строгий слабый порядок (не равенство). Кроме того, компаратор должен вызываться с аргументами в обоих порядках:
comparator(*iter, value); // items less than lower bound
comparator(value, *iter); // items greater than upper bound
Таким образом, результатом equal_range является диапазон итераторов, в котором оба этих вызова возвращают false
.
Таким образом, простая настройка заключается в добавлении конструктора к вашему MultiValuedComparator, который принимает Thing, что позволяет преобразовать объект Thing в объект MultiValuedComparator для сравнения:
class MultiValuedComparator
{
public:
item a;
item b;
MultiValuedComparator(item c, item d)
{
a = c;
b = d;
}
MultiValuedComparator(const Thing &thing)
{
a = thing.a
b = thing.b
}
};
А затем настройте компаратор так, чтобы он использовал только MultiValuedComparator и использовал строгий слабый порядок:
struct RangeByA : public std::binary_function<MultiValuedComparator, MultiValuedComparator>
{
bool operator()(const MultiValuedComparator &left, const MultiValuedComparator &right)
{
// Sorted by a first, then b if necessary
return (left.a < right.a)
|| (!(right.a < left.a) && (left.b < right.b)));
}
};
Альтернативой вышеупомянутому, которая позволит избежать копирования (из Thing в MultiValuedComparator), является простая реализация operator()
в обоих направлениях (Thing против MultiValuedComparator и MultiValuedComparator против Thing), отбрасывая наследование std::binary_function
( здесь не нужен):
struct RangeByA
{
bool operator()(const Thing &left, const MultiValuedComparator &right) {
// ... (same body as above)
}
bool operator()(const MultiValuedComparator &left, const Thing &right) {
// ... (same body as above)
}
};