upper_bound和lower_bound不一致的值要求

时间:2015-11-09 03:09:51

标签: c++ stl implicit-conversion lower-bound upperbound

我看到了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;
}

1 个答案:

答案 0 :(得分:5)

我不认为这是一个错误。如果您查看(possible) implementation of std::upper_bound,则会进行比较,如

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

因为operator<MyInt的成员函数(而不是int的成员函数,这不是类类型),代码不会编译,因为有MyInt没有从int转换为*it。另一方面,在std::lower_bound中,value出现在比较的lhs上,int(类型MyInt)可以隐式转换为MyInt::operator<传递给if (*it < value) { ... } // lower_bound, implicit conversion `int`->`MyInt` works

MyInt::operator int(){return val;}

这就是为什么将比较运算符作为非成员实现更好的原因,因此您不会有这种不对称性。 Scott Meyers也提到了这一点。 Effective C++ book:第24项:当类型转换应适用于所有参数时,声明非成员函数。

快速而又脏的修复:为隐式转换MyInt定义intset<MyInt>::iterator itU = upper_bound(s.begin(), s.end(), MyInt(2)); 。 (编辑:并不真正有效,含糊不清)。有效的是消除了隐式转换的需要

66,61,47
64
91,82,86,78,88,4,2,15,87,3
69,71,70,97,3,45

代替。