1:
请看如下代码:
-
#include
-
#include
-
using namespace std;
-
-
int main()
-
{
-
complex<int> a(1, 2);
-
mapint>, int> k;
-
-
return 0;
-
}
以上代码运行正常。
2:
继续看如下代码:
-
#include
-
#include
-
using namespace std;
-
-
int main()
-
{
-
complex<int> a(1, 2);
-
mapint>, int> k;
-
k[a] = 5;
-
return 0;
-
}
以上代码出错了。
原因是: 当执行 k[a] = 5 时, 即向 k 加入了一个新的 pair, int> 型的元素,而map是会自动对元素进行排序,排序的方式是按key的大小来排序。但complex却没有定义对复数比较的函数,于是map就不知如何比较complex,最终导致编译错误。
3:
自以为对的扩展complex类:
-
#include
-
#include
-
using namespace std;
-
-
bool operator< (complex<int> l, complex<int> r)
-
{
-
if (l.real() < r.real()) return true;
-
else return false;
-
}
-
-
int main()
-
{
-
complex<int> a(1, 2), b(3, 4);
-
mapint>, int> k;
-
k[a] = 5;
-
return 0;
-
}
以上编译错误。按理只要重载小于运算符(因为map默认按小于排序),就应该可以的啦,但还是编译不过。错误信息和2的一样,还是由于没找到比较complex的函数
.
3-1:
真的没找到?
-
#include
-
#include
-
using namespace std;
-
-
bool operator< (complex<int> l, complex<int> r)
-
{
-
return (l.real() < r.real());
-
}
-
-
int main()
-
{
-
complex<int> a(1, 2), b(3, 4);
-
mapint>, int> k;
-
-
a < b;
-
return 0;
-
}
以上代码运行正常。
以上代码编译通过。至少证明complex的小于运算符是重载成功的。但map又怎么会找不到呢?
3-2:
侧面验证:
-
#include
-
using std::map;
-
-
template <class T>
-
class complex
-
{
-
public:
-
complex(T real){this->treal = real;}
-
T real(){return treal;}
-
private:
-
T treal;
-
};
-
-
-
bool operator< (complex<int> l, complex<int> r)
-
{
-
return (l.real() < r.real());
-
}
-
-
-
int main()
-
{
-
mapint>, int> k;
-
complex<int> a(1);
-
k[a] = 5;
-
return 0;
-
}
以上编译通过。
我自编了一个极其简陋complex类(其实只是名字一样罢了),其余没变,map似乎又找到了complex的小于运算符了。怪哉!
4:
思考:
重载的complex的小于运算符没有错。那么,请大家比较一下3和3-2,3用的是stl里的complex,3-2用的是我编的 “complex”,两者有什么根本的不同?
答:内容不同咯!
但两者都有complex的小于运算符,但在3中map又为何找不到呢?
所有的证据都指向了-------namespace std
5:
验证:
-
#include
-
#include
-
using namespace std;
-
-
namespace std
-
{
-
bool operator < (complex<int> l, complex<int> r)
-
{
-
return l.real() < r.real();
-
}
-
}
-
-
-
int main()
-
{
-
mapint> , int> k;
-
complex<int> a(1,2);
-
k[a] = 5;
-
return 0;
-
}
以上编译成功了~
6:
map/set 的 “陷阱”:
以上所有代码我虽然只用了map来测试,事实上set也一样的。
所谓陷阱,其实也只不过是一些不容易发现或者平时没留意的一些细节:
map的完整参数是这样的——map< class Key, class T, class Compare = less, class Allocator = allocator< pair > >
当class Key的域是在std中, class Compare就会自动到std中去找key的小于函数。
若class Key 的域不在std中, class Compare就会不会到std中去找key的小于函数。
即map/set是根据Key的域来寻找Key的比较函数。
7:
以上推理仅个人意见,如有不当,恳请指出。
http://blog.csdn.net/kof2001kop/article/details/6695024