upper_bound 有 binary_function Visual Studio 2008 错误?

upper_bound With binary_function Visual Studio 2008 Bug?

1st 是的,我一直在使用 Visual Studio 2008,我相信这个错误是 Visual Studio 2008 特有的。

我正在尝试编写一个函子来比较我的结构中的 1 个成员,这样我就可以对由该成员排序的所述结构的 vector 执行 upper_bound。这很难用语言解释,所以这里有一个例子:

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 给我错误:

error C2664: 'bool comp::operator ()(const double,const Foo &)' : cannot convert parameter 1 from 'Foo' to 'const double'

我怀疑在通过交换输入来测试仿函数严格弱排序的实现中存在一些问题。是否有一种解决方法可以暂停对编译器的检查,或者我只需要将我的仿函数更改为接收 2 Foos 并创建一个临时的 Foo 来代表这里的 2?

已经 Algirdas Preidžius mentioned it is because of strict weak orderings 检查。

作为解决方法,您可以同时定义这两个运算符。

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; }
};

this is a Debug only implementation error in Visual Studio 2008. It has been corrected on .

该错误存在于 Microsoft 的 C++ 实现代码中,并且由 _HAS_ITERATOR_DEBUGGING 控制,因此如果禁用它是一个选项,请考虑将“_HAS_ITERATOR_DEBUGGING=0”添加到您的 "Preprocessor Definitions"。

如果您不喜欢禁用迭代器检查的想法,您需要通过禁用 _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 好像一直认为是undefined
  2. 如果您的特定情况需要 comp 在多个地方使用,我的代码定义 comp 内联 1st 考虑包装整个 else-block 在函数中限制代码中 #define 的数量,如果您在多个标准算法中使用 comp,显然此注释的适用性将受到限制