Std:: lower_bound и функция компаратора с разными типами?

У меня есть массив структур, отсортированный по члену структуры, что-то вроде:

struct foo
{
    int bar;
    double baz;
};

// An array of foo, sorted on .bar
foo foos[] = { ........ };
// foos[0] = {0, 0.245}
// foos[1] = {1, -943.2}
// foos[2] = {2, 304.222}
// etc...

Я хочу найти элемент с определенным значением .bar. Это может быть или не быть в массиве, и я бы хотел сделать это в O (log (n)) времени, так как массив отсортирован.

std::lower_bound - это то, что я обычно использую, но мне нужно указать функцию сравнения. Однако тип элементов массива (struct foo) и искомое значение (int) не совпадают, поэтому мой компаратор:

bool comp(foo a, int b)
{
    // ...
}
// --- or ---
bool comp(int a, foo b)
{
    // ...
}

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

Я хотел бы избежать создания foo для перехода к std::lower_bound здесь, поскольку полный foo не требуется и может быть дорогостоящим. Моим другим вариантом было бы обернуть foo * в пользовательский итератор, который только открыл элемент .bar.

Ответы

Ответ 1

Из стандарта, 25.3.3.1/3, на std::lower_bound():

Возвращает. Дальнейший итератор i в диапазоне [first, last] такой что для любого итератора j в диапазоне [first, i) следует следующее соответствующие условия: *j < value или comp(*j, value) != false.

Из этого вы можете использовать

bool comp(foo a, int b)

или вы можете сравнить два экземпляра foo, а затем получить доступ к bar в обоих из них.

Ответ 2

Это действительно должен быть комментарий к сообщению wilhelmtell, но у меня нет достаточного количества баллов, чтобы сделать это еще...

Я просто хотел указать, что это также работает для компилятора MS, но вам нужно определить

comp(foo lhs, foo rhs)

иначе ваш код не будет компилироваться в режиме отладки.