自定义std::sort的比较函数时发生"invalid operator<"错误原因

VS2008的sort()函数的用法貌似挺郁闷的。。。

前些时候写了个sort的compare函数,错误"Expression : invalid operator <",baidu+google了一下,没有找到比较明确的说法,不过找到了微软的一个网页,说得算是很清楚,不过看得不太明白。意思大概是出这个错是因为VS2005,VS2008后的sort()里,用的是所谓的“ strict weak ordering”,也就是说,如果a==b,则返回的应该是false,如果返回的是true,则会出上面的错。

网页:http://support.microsoft.com/kb/949171

以下摘抄网页中的说法:

1.strict weak ordering

举例说明如下:

 


· Strict: pred(X, X) is always false.

· Weak: If !pred(X, Y) && !pred(Y, X), X==Y.

· Ordering: If pred(X, Y) && pred(Y, Z), then pred(X, Z).

2.出现"Expression : invalid operator <"的写法

bool CustPredicate (int elem1, int elem2 )
{
    if(elem1 > elem2)
        return true; 

    if (elem1 < elem2)
        return false;
    return true;
}

3.为了解决错误,应把以上代码改写为以下两种中的任一种:

(1)

bool CustPredicate (int elem1, int elem2 )
{
    if(elem1 > elem2)
        return true; 

    if (elem1 < elem2)
        return false;

    return false; //Should return false if both the vaules are same
}

(2)

Second Option:-
bool CustPredicate (int elem1, int elem2 )
{
    return elem1 > elem2;
}

 

Im using hgeVector in a std::map as the key. My Tile class is the value.

/** needed for sorting by vector in map */constbooloperator<( const hgeVector& a, const hgeVector& b ) { if ( a.x < b.x && a.y < b.y ) returntrue; if ( a.x > b.x && a.y > b.y ) returnfalse; return ( a.x < b.x || a.y < b.y ); } typedef std::map<hgeVector, Tile*> TileMap;



The problem arises when doing std::map[ position ] = new Tile( id );, the map asserts and gives the error "invalid operator<".

However, the first time I insert something into the map it works, but the second time, I get the assert. The first key I insert is (6,-3), which works, but the second one, (7,-4), asserts.

The plan with the operator is simple; if both x and y is less, a is less. Else, if neither is less, a is not less. Then the special case; if x or y has the same value, a is less if either is less.

Where is my misstake? 

0

Back to top of the page up there ^

Ad: Attend the Game/AI Conference June 23-24 #2     Gage64     MemberGroup:Members Reputation: 701

  Posted 10 June 2008 - 09:32 PM

I think this is because your operator< is faulty. For example, (6, -3) < (7, -4) and (7, -4) < (6, -3) both return true, but obviously that doesn't make sense.

You should reconsider what less-than means for vectors. Probably the best option would be a sort of lexicographic compare:

const bool operator<( const hgeVector& a, const hgeVector& b ){ return (a.x < b.x) || ( (a.x == b.x) && (a.y < b.y) );}
OOP Articles | C++: A Dialog (free book) | Thinking in C++ (free book) | Google Books - Free preview for many books Back to top of the page up there ^ #3     chairthrower     MemberGroup:Members Reputation: 224

  Posted 10 June 2008 - 09:32 PM


I havent got the raw brainpower to be able to trace through the logic - but this is the way I structure comparators which I find is fairly readble. we just test each dimension and whether we need another dimension to help resolve otherwise returning false.

const bool operator<( const hgeVector& a, const hgeVector& b )
{
if ( a.x != b.x) return a.x < b.x; // first dim
if ( a.y != b.y) return a.y < b.y; // second dim 
return false; // false in case of equality

Back to top of the page up there ^ #4     Mizipzor     MemberGroup:Members Reputation: 98

  Posted 10 June 2008 - 09:52 PM

Original post by Gage64 For example, (6, -3) < (7, -4) and (7, -4) < (6, -3) both return true, but obviously that doesn't make sense.


Very true indeed, I wonder how I couldnt spot that. :p

Anyways, both your snippets work, thanks and ++rating to you both! :)


Back to top of the page up there ^ #5     godecho     MemberGroup:Members Reputation: 90

  Posted 11 June 2008 - 03:18 AM

I'm just making a guess about the data types your vector holds, but remember there's something to  keep in mind  when performing equality tests on floats. Both of the solutions suggested here perform equality tests. They might be fine for your situation, but it's something that should be considered. 
Back to top of the page up there ^ #6     Sneftel     Moderator - Consoles, PDAs, and Cell PhonesGroup:Senior Moderators Reputation: 1077

  Posted 11 June 2008 - 03:43 AM

Original post by godecho
I'm just making a guess about the data types your vector holds, but remember there's something to  keep in mind  when performing equality tests on floats. Both of the solutions suggested here perform equality tests. They might be fine for your situation, but it's something that should be considered.

Actually, it isn't... or, at least, it doesn't turn out to matter. For all the vagaries of floating point math, trichotomy still holds true for real numbers in IEEE-754, and that's all that's needed here. Of course, the resultant ordering isn't going to be particularly coherent, but that's to be expected from any ℜ2→ℜ mapping. 
Back to top of the page up there ^ #7     chairthrower     MemberGroup:Members Reputation: 224

  Posted 11 June 2008 - 03:53 AM

Original post by godecho
I'm just making a guess about the data types your vector holds, but remember there's something to  keep in mind  when performing equality tests on floats. Both of the solutions suggested here perform equality tests. They might be fine for your situation, but it's something that should be considered.


Also mixing and matching == and < should probably not be considered good style given the distinction made in stl between the seperate concepts of equality and equivalence - sorry i cant find a good link but scott meyers covers it in  effective stl . However for a practical use case that is not generic and confined to floats types i dont think its an issue. 
Back to top of the page up there ^ #8     godecho     MemberGroup:Members Reputation: 90

  Posted 11 June 2008 - 06:10 AM

Original post by Sneftel
Actually, it isn't... or, at least, it doesn't turn out to matter. For all the vagaries of floating point math, trichotomy still holds true for real numbers in IEEE-754, and that's all that's needed here. Of course, the resultant ordering isn't going to be particularly coherent, but that's to be expected from any ℜ2→ℜ mapping.
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值