今天在VS中遇到一个十分诡异的事情,先看下面这个简单的程序:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 | #include <iostream> #include <set> #include <algorithm> using namespace std; class cmp { public: bool operator()(long long l, long long r) { //~ 此间内容可略去不看。 //~ 如果l和r含有的digits完全相同则返回false, //~ 如125 vs. 512 char tmp1[1024], tmp2[1024]; sprintf(tmp1,"%ld",l); sprintf(tmp2,"%ld",r); sort(tmp1, tmp1+strlen(tmp1)); sort(tmp2, tmp2+strlen(tmp2)); if (!strcmp(tmp1, tmp2)) { return false; } return true; } }; int main(int argc, char* argv[]) { set<long long,cmp > Set; int a[15]; Set.insert(1); Set.insert(2); //~ 此处疯狂 return 0; } |
程序在这个地方跑偏了,弹出这么个东西

可是set的key_compare我一直都是这么用的啊。把程序拷到Linux下面用g++就一切正常。望达人指教。
更新
Johnny同学给的贴文中提到了,一个predicate对于任两个参数a,b不能返回两个true,即pred(a, b)和pred(b, a)不能同时返回true,这是strict weak规则决定的。代码为证:
1 2 3 4 5 6 7 8 9 10 | template<class _Pr, class _Ty1, class _Ty2> inline bool __CLRCALL_OR_CDECL _Debug_lt_pred(_Pr _Pred, _Ty1& _Left, _Ty2& _Right, const wchar_t *_Where, unsigned int _Line) { // test if _Pred(_Left, _Right) and _Pred is strict weak ordering if (!_Pred (_Left, _Right)) return (false); else if (_Pred(_Right, _Left)) _DEBUG_ERROR2("invalid operator<", _Where, _Line); return (true); } |
即是说,在调试时(特指Visual Studio的debug模式),bool _Debug_lt_pred()模板函数会对pred(a, b)的返回结果进行检查。如果pred(a, b)返回false没有问题。但如果其返回true,那么_Debug_lt_pred还会对pred(b, a)进行检查,若也返回true就会触发assert(有上图为证)。
对于本文最初的代码,为了通过的_Debug_lt_pred的检查,我可以:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 | class cmp { public: bool operator()(long long l, long long r) { //~ …… if (!strcmp(tmp1, tmp2)) { return false; } else return l < r; } }; |
这样就保证了cmp::(long long, long long)不会返回“两个true”了
你好!除了代码,此处没有多少原创之物,皆为本人搜集、整理、总结之记录与心得,欢迎转载分享!转载时请尽量注明出处,将不胜感激。祝你健康、快乐!
PLEASE REFER TO:
http://www.cnblogs.com/clever101/archive/2010/02/22/1671543.html
谢谢!
以前看到strict weak predicate总是忽略,原来问题最终出在这里。
那我该怎么实现我想要的pred呢?
vs2008下 debug模式下运行出错,release版下正常执行。
怀疑是debug版的配置与release版不同导致的。
弄不明白VS的debug和release.