upper_bound和lower_bound不一致的值要求

upper_bound and lower_bound inconsistent value requirements

本文关键字:bound lower upper 不一致      更新时间:2023-10-16

我看到了 std::lower_bound(( 和 std::upper_bound(( 语法中的不一致(嗯,类型转换,真的(,想知道是否有人可以阐明?根据评论,尽管第 2 行与第 1 行明显相似,但它将无法编译;您需要使用第 3 行中显示的表单(至少在 GCC 4.7.3/Ubuntu 64 位上 - 这就是我要玩的全部内容(

#include <set>
#include <algorithm>
using namespace std;
class MyInt {
  private:
    int val;
  public:
    MyInt(int _val): val(_val) {}
    bool operator<(const MyInt& other) const {return val < other.val;}
};
int main() {
    set<MyInt> s;
    s.insert(1);  // demonstrate implicit conversion works
    s.insert(MyInt(2));
    s.insert(3); // one last one for the road
    set<MyInt>::iterator itL = lower_bound(s.begin(), s.end(), 2); //LINE 1
    // the line below will NOT compile
    set<MyInt>::iterator itU = upper_bound(s.begin(), s.end(), 2); //LINE 2
    // the line below WILL compile
    set<MyInt>::iterator itU2 = upper_bound(s.begin(), s.end(), MyInt(2)); // LINE 3
    return 0;
}

我不认为这是一个错误。如果你看一下std::upper_bound的(可能的(实现,比较是这样的

if (!(value < *it)) { ... } // upper_bound, implicit conversion `MyInt`->`int` doesn't work

并且由于operator<MyInt的成员函数(而不是int的成员函数,它不是类类型(,因此代码无法编译,因为没有从MyIntint的转换。另一方面,在std::lower_bound中,*it出现在比较的 lhs 上,并且value(类型 int(在传递给 MyInt::operator< 时可以隐式转换为 MyInt

if (*it < value) { ... } // lower_bound, implicit conversion `int`->`MyInt` works
这就是为什么

最好将比较运算符实现为非成员的原因,这样您就不会有这种不对称性。Scott Meyers 的《有效C++》一书中也提到了这一点:第 24 项:当类型转换应应用于所有参数时声明非成员函数

快速和脏修复:定义一个MyInt::operator int(){return val;},用于隐式转换MyIntint。(编辑:实际上不起作用,模棱两可(。有效的方法是消除隐式转换的需要
set<MyInt>::iterator itU = upper_bound(s.begin(), s.end(), MyInt(2));

相反。