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

来源:互联网 发布:农爱帮软件下载 编辑:程序博客网 时间:2024/05/21 08:24

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 booksBack 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 Gage64For 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 keepinmind 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 keepinmind 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 keepinmind 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.
原创粉丝点击