upper_bound с бинарной функцией Visual Studio 2008 Ошибка?

1улица да, я застрял в Visual Studio 2008 и считаю, что эта ошибка характерна только для Visual Studio 2008.

Я пытаюсь написать функтор, чтобы сравнить только 1 член моей структуры, чтобы я мог сделать upper_bound на vector из указанных структур, которые отсортированы по этому члену. Это сложно объяснить словами, вот пример:

struct Foo {
int a;
char b;
};

struct comp : binary_function<const double, const Foo&, bool> {
bool operator () (const double lhs, const Foo& rhs) { return lhs < rhs.a; }
};

int main() {
vector<Foo> test;

for(int i = 0; i < 5; ++i) {
Foo foo = { i + 1, 'a' + i };

test.push_back(foo);
}

cout << upper_bound(test.begin(), test.end(), 2, comp())->b << endl;
}

Это прекрасно работает на Visual Studio 2015. Но Visual Studio 2008 выдает мне ошибку:

ошибка C2664: ‘bool comp :: operator () (const double, const Foo &) ‘: невозможно преобразовать параметр 1 из’ Foo ‘в’ const double ‘

Я подозреваю, что в реализации есть какое-то зло, когда функтор проверяется на строго слабое упорядочение путем замены входных данных. Есть ли обходной путь, чтобы приостановить эту проверку на компиляторе, или мне просто нужно просто поменять свой функтор на 2? Fooи сделать временный Foo представлять 2 здесь?

2

Решение

Как заявил Альгирдас Преиджюс это ошибка реализации только для отладки в Visual Studio 2008. Она была исправлена ​​на .

Ошибка в коде реализации Microsoft C ++, и она устраняется _HAS_ITERATOR_DEBUGGING поэтому, если вы отключите эту опцию, попробуйте добавить «_HAS_ITERATOR_DEBUGGING = 0» в «Определения препроцессора».

Если вам не нравится идея отключения проверки итератора, вам нужно обойти это путем отключения _HAS_ITERATOR_DEBUGGING поэтому ваш код будет выглядеть примерно так:

struct Foo {
int a;
char b;
};

int main() {
vector<Foo> test;

for(int i = 0; i < 5; ++i) {
Foo foo = { i + 1, 'a' + i };

test.push_back(foo);
}

#if _HAS_ITERATOR_DEBUGGING
for(vector<Foo>::const_iterator it = test.begin(); it != test.end(); ++it) {
if(it->a > 2) {
cout << it->b << endl;
break;
}
}
#else
struct comp : public binary_function<const double, const Foo&, bool> {
bool operator () (const double lhs, const Foo& rhs) { return lhs < rhs.a; }
};

cout << upper_bound(test.begin(), test.end(), 2, comp())->b << endl;
#endif
}

Пара замечаний здесь:

  1. Обратите внимание, что я использую #if что означает if-блок будет выполняться только если _HAS_ITERATOR_DEBUGGING определен и не равен 0. Во время разработки Visual Studio 2008, кажется, всегда думает, что он не определен
  2. Мой код определяет comp встроенный, если ваша конкретная ситуация требует comp чтобы используется в нескольких местах 1улица подумайте об упаковке всего этого else-блок в функции для ограничения количества #defineв вашем коде, очевидно, что применимость этого комментария будет ограничена, если вы используете comp в нескольких стандартных алгоритмах
1

Другие решения

Как уже Альгирдас Преиджюс упомянул это из-за строгие слабые порядки проверка.

В качестве обходного пути вы можете определить оба оператора.

struct comp {
bool operator () (const double lhs, const Foo& rhs) { return lhs < rhs.a; }
bool operator () (const Foo& lhs, const double rhs) { return lhs.a < rhs; }
};
-1