5

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

1 回答 1

5

我不认为这是一个错误。如果您查看 的(可能的)实现std::upper_bound,则比较类似于

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

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

if (*it < value) { ... } // lower_bound, implicit conversion `int`->`MyInt` works

这就是为什么最好将比较运算符实现为非成员的原因,所以你没有这种不对称性。Scott Meyers 的Effective C++书中也提到了这一点: Item 24: Declare non-member functions when type conversions should apply to all parameters

快速而肮脏的修复:定义一个MyInt::operator int(){return val;}for 隐式转换MyIntint. (编辑:真的不起作用,模棱两可)。有效的是消除隐式转换的需要

set<MyInt>::iterator itU = upper_bound(s.begin(), s.end(), MyInt(2));

反而。

于 2015-11-09T03:18:55.133 回答