有关小于操作符的重载

xjtudaniel 2008-07-29 10:02:14
自定义了一个类Test,定义了如下函数
bool operator<(const Test& other){};
然后定义一个vector<Test> test;
调用sort(test.begin(),test.begin()+5),编译的时候报错

但是将重载操作符声明为const就可以成功编译
bool operator<(const Test& other) const {};

请问sort()函数对于底层对象重载小于操作符必须要求是const的吗?查文档没发现哪里描述了这个啊..
...全文
290 12 打赏 收藏 转发到动态 举报
AI 作业
写回复
用AI写文章
12 条回复
切换为时间正序
请发表友善的回复…
发表回复
elegant87 2008-08-07
  • 打赏
  • 举报
回复
学习一下!很好!
ronliu 2008-07-31
  • 打赏
  • 举报
回复
const
xjtudaniel 2008-07-30
  • 打赏
  • 举报
回复
[Quote=引用 4 楼 IanFang 的回复:]
你编译不过去的原因是因为某些STL版本对sort的实现使用了一些辅助函数,其参数是const的引用类型,如sgi STL是这个函数阻止了你;
template <typename _Tp>
inline const _Tp&
__median(const _Tp& __a, const _Tp& __b, const _Tp& __c)
{
// concept requirements
__glibcxx_function_requires(_LessThanComparableConcept <_Tp>)
if (__a < __b)
if (__b < __c)
return __…
[/Quote]

我从编译提示的错误看出来是sgi STL的要求问题,只是没看懂提示的那块,另外,你举的例子也并没有反映sort底层对象的<要求是const的

另外,将函数参数改变为传值调用仍然报编译错误
xjtudaniel 2008-07-30
  • 打赏
  • 举报
回复
[Quote=引用 2 楼 iu_81 的回复:]
bool operator <(const Test& other) const {};
上面的const是必须的,因为other 是const的,如果函数不在形式上声明const,显然,编译器会认为该函数可能修改了这个引用的对象,将会报错。
因此,如果函数是非const的,操作符重载的参数不要写成const。当然,这在某种程度上可能破坏完整性。
[/Quote]

即使将参数声明为非const的,也不能编译通过,的确,这个错误与不同的编译器的实现有关系,在g++下有错误,但是在vs 2008下就可以正常运行

对于任何不修改类成员和不调用非const的成员函数的函数,都应该定义成const的是没错,从合理性上的确如一楼所说应该如此...

我只是想问一下这个编译出错的具体原因,是什么标准中定义了吗?

IanFang 2008-07-30
  • 打赏
  • 举报
回复
sort的实现比较复杂,它用的些辅助函数如上面的__median(const _Tp& __a, const _Tp& __b, const _Tp& __c) 里面的比较
动作:if (__a < __b)显然要求你的operator<为const的,没说要你改operator<为传值调用,我是说假如,仅仅是假如,那些辅助函数也不专业的使用递值调用而不使用常引用的话, 你的operator<不用const也就能通过编译了。这只是给你解释你问的问题,没有文档要求<为const而实际上却需要const.
Gob00st 2008-07-29
  • 打赏
  • 举报
回复
[Quote=引用 6 楼 xkyx_cn 的回复:]
sort里是对象的常引用对比较函数发起调用的,所以比较函数也要为const成员函数
[/Quote]
xkyx_cn 2008-07-29
  • 打赏
  • 举报
回复
sort里是对象的常引用对比较函数发起调用的,所以比较函数也要为const成员函数
wjb_yd 2008-07-29
  • 打赏
  • 举报
回复
如果不定义成const,你能比较3和5的大小么?
IanFang 2008-07-29
  • 打赏
  • 举报
回复
你编译不过去的原因是因为某些STL版本对sort的实现使用了一些辅助函数,其参数是const的引用类型,如sgi STL是这个函数阻止了你;
template<typename _Tp>
inline const _Tp&
__median(const _Tp& __a, const _Tp& __b, const _Tp& __c)
{
// concept requirements
__glibcxx_function_requires(_LessThanComparableConcept<_Tp>)
if (__a < __b)
if (__b < __c)
return __b;
else if (__a < __c)
return __c;
else
return __a;
else if (__a < __c)
return __a;
else if (__b < __c)
return __c;
else
return __b;
}

如果抛开效率此函数也可以实现为传值调用,这样就不会有问题了。

operator<不定义为const其实是你的违例。
IanFang 2008-07-29
  • 打赏
  • 举报
回复
没有理由不把operator<实现为const的。
iu_81 2008-07-29
  • 打赏
  • 举报
回复
bool operator <(const Test& other) const {};
上面的const是必须的,因为other 是const的,如果函数不在形式上声明const,显然,编译器会认为该函数可能修改了这个引用的对象,将会报错。
因此,如果函数是非const的,操作符重载的参数不要写成const。当然,这在某种程度上可能破坏完整性。

arong1234 2008-07-29
  • 打赏
  • 举报
回复
从合理性上讲,没有任何理由不把他设置为const,因此报错是一种比较好的行为
不过报错不报错可能和编译器有关,虽然我的想法是不应该强制要求,但是比较聪明的编译器可能会给你一个警告
1、抽象类与操作符重载 定义表示形状的抽象类及相应的派生类,并实现相关操作符重载。 (1)定义表示形状的抽象类Shape: 添加公有成员函数double Area(),用于计算形状面积;定义为纯虚函数; 添加公有成员函数void Show(),用于显示形状信息,定义为纯虚函数; 定义虚的析构函数; 重载比较操作符:==、>和<,用于比较两个形状面积的大小关系,返回值类型为bool,可以定义为成员函数或友元函数。 、、、、、、 2、虚函数 利用虚函数实现多态: (1)设计Person类,要求具有用于表示姓名的保护数据成员:string szName; 实现信息打印的公有成员函数:void Print()。其中,Print函数设计为虚函数,输出的信息格式为:“Person 姓名”。 、、、、、、 3、操作符重载 定义有理数类(分母不为0的分数,分子分母均为整数)Rational,实现相应操作符重载。 (1)定义私有数据成员:分子int iUp; 分母 int iDown。 (2)定义私有成员函数:void Reduce() 和 int Gcd(int l, int r),分别用于有理数的约简和求两个整数的最大公约数。其中,在约简时需要求取分子与分母的最大公约数。 、、、、、、 4、记录文件的读写操作 源数据文件(文本格式)中包含有每个学生的记录:ID(身份识别号)、 Gender(性别)、 Birthday(生日)和EnrollmentDate(入学时间),字段之间以半角逗号分隔,记录之间以换行符分隔。要求从源数据文件中读取学生记录并删除重复记录,然后根据ID大小对所有记录按从小到大排序,将排序后的记录保存到目标文件中并同时输出到屏幕上。 、、、、、、 5、简单文本文件的读写 、、、、、

65,199

社区成员

发帖
与我相关
我的任务
社区描述
C++ 语言相关问题讨论,技术干货分享,前沿动态等
c++ 技术论坛(原bbs)
社区管理员
  • C++ 语言社区
  • encoderlee
  • paschen
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
  1. 请不要发布与C++技术无关的贴子
  2. 请不要发布与技术无关的招聘、广告的帖子
  3. 请尽可能的描述清楚你的问题,如果涉及到代码请尽可能的格式化一下

试试用AI创作助手写篇文章吧