upper_bound和lower_bound取值要求不一致
upper_bound and lower_bound inconsistent value requirements
我看到 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;
}
我不认为这是一个错误。如果你看 (possible) implementation of std::upper_bound
,比较就像
if (!(value < *it)) { ... } // upper_bound, implicit conversion `MyInt`->`int` doesn't work
并且因为 operator<
是 MyInt
的成员函数(而不是 int
的成员函数,后者不是 class 类型),代码无法编译,因为没有从 MyInt
到 int
的转换。另一方面,在std::lower_bound
中,*it
出现在比较的lhs上,value
(类型int
)可以隐式转换为MyInt
当传递给 MyInt::operator<
.
if (*it < value) { ... } // lower_bound, implicit conversion `int`->`MyInt` works
这就是为什么最好将比较运算符实现为非成员的原因,这样就不会出现这种不对称性。 Scott Meyers 的 Effective C++ 书中也提到了这一点:项目 24:当类型转换应用于所有参数时声明非成员函数.
快速而肮脏的修复:定义一个 MyInt::operator int(){return val;}
用于隐式转换 MyInt
到 int
。 (编辑: 并没有真正起作用,歧义)。有效的是消除对隐式转换的需要
set<MyInt>::iterator itU = upper_bound(s.begin(), s.end(), MyInt(2));
相反。
我看到 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;
}
我不认为这是一个错误。如果你看 (possible) implementation of std::upper_bound
,比较就像
if (!(value < *it)) { ... } // upper_bound, implicit conversion `MyInt`->`int` doesn't work
并且因为 operator<
是 MyInt
的成员函数(而不是 int
的成员函数,后者不是 class 类型),代码无法编译,因为没有从 MyInt
到 int
的转换。另一方面,在std::lower_bound
中,*it
出现在比较的lhs上,value
(类型int
)可以隐式转换为MyInt
当传递给 MyInt::operator<
.
if (*it < value) { ... } // lower_bound, implicit conversion `int`->`MyInt` works
这就是为什么最好将比较运算符实现为非成员的原因,这样就不会出现这种不对称性。 Scott Meyers 的 Effective C++ 书中也提到了这一点:项目 24:当类型转换应用于所有参数时声明非成员函数.
快速而肮脏的修复:定义一个 。 (编辑: 并没有真正起作用,歧义)。有效的是消除对隐式转换的需要MyInt::operator int(){return val;}
用于隐式转换 MyInt
到 int
set<MyInt>::iterator itU = upper_bound(s.begin(), s.end(), MyInt(2));
相反。