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 здесь?
Как заявил Альгирдас Преиджюс это ошибка реализации только для отладки в Visual Studio 2008. Она была исправлена на зрительно-студия-2010.
Ошибка в коде реализации 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
}
Пара замечаний здесь:
#if
что означает if
-блок будет выполняться только если _HAS_ITERATOR_DEBUGGING
определен и не равен 0. Во время разработки Visual Studio 2008, кажется, всегда думает, что он не определенcomp
встроенный, если ваша конкретная ситуация требует comp
чтобы используется в нескольких местах 1улица подумайте об упаковке всего этого else
-блок в функции для ограничения количества #define
в вашем коде, очевидно, что применимость этого комментария будет ограничена, если вы используете comp
в нескольких стандартных алгоритмахКак уже Альгирдас Преиджюс упомянул это из-за строгие слабые порядки проверка.
В качестве обходного пути вы можете определить оба оператора.
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; }
};