下面是map定義的結構:
// TEMPLATE CLASS map
template<class _Kty,
class _Ty,
class _Pr = less<_Kty>,
class _Alloc = allocator<pair<const _Kty, _Ty> > >
class map
: public _Tree<_Tmap_traits<_Kty, _Ty, _Pr, _Alloc, false> >
{ // ordered red-black tree of {key, mapped} values, unique keys
public:
typedef map<_Kty, _Ty, _Pr, _Alloc> _Myt;
typedef _Tree<_Tmap_traits<_Kty, _Ty, _Pr, _Alloc, false> > _Mybase;
typedef _Kty key_type;
typedef _Ty mapped_type;
typedef _Ty referent_type; // retained
typedef _Pr key_compare;
typedef typename _Mybase::value_compare value_compare;
typedef typename _Mybase::allocator_type allocator_type;
typedef typename _Mybase::size_type size_type;
typedef typename _Mybase::difference_type difference_type;
typedef typename _Mybase::pointer pointer;
typedef typename _Mybase::const_pointer const_pointer;
typedef typename _Mybase::reference reference;
typedef typename _Mybase::const_reference const_reference;
typedef typename _Mybase::iterator iterator;
typedef typename _Mybase::const_iterator const_iterator;
typedef typename _Mybase::reverse_iterator reverse_iterator;
typedef typename _Mybase::const_reverse_iterator
const_reverse_iterator;
typedef typename _Mybase::value_type value_type;
map()
: _Mybase(key_compare(), allocator_type())
{ // construct empty map from defaults
}
explicit map(const key_compare& _Pred)
: _Mybase(_Pred, allocator_type())
{ // construct empty map from comparator
}
map(const key_compare& _Pred, const allocator_type& _Al)
: _Mybase(_Pred, _Al)
{ // construct empty map from comparator and allocator
}
template<class _Iter>
map(_Iter _First, _Iter _Last)
: _Mybase(key_compare(), allocator_type())
{ // construct map from [_First, _Last), defaults
_DEBUG_RANGE(_First, _Last);
for (; _First != _Last; ++_First)
this->insert(*_First);
}
template<class _Iter>
map(_Iter _First, _Iter _Last,
const key_compare& _Pred)
: _Mybase(_Pred, allocator_type())
{ // construct map from [_First, _Last), comparator
_DEBUG_RANGE(_First, _Last);
for (; _First != _Last; ++_First)
this->insert(*_First);
}
template<class _Iter>
map(_Iter _First, _Iter _Last,
const key_compare& _Pred, const allocator_type& _Al)
: _Mybase(_Pred, _Al)
{ // construct map from [_First, _Last), comparator, and allocator
_DEBUG_RANGE(_First, _Last);
for (; _First != _Last; ++_First)
this->insert(*_First);
}
#if _HAS_STRICT_CONFORMANCE
void erase(iterator _Where)
{ // erase element at _Where
_Mybase::erase(_Where);
}
size_type erase(const key_type& _Keyval)
{ // erase and count all that match _Keyval
return (_Mybase::erase(_Keyval));
}
void erase(iterator _First, iterator _Last)
{ // erase [_First, _Last)
_Mybase::erase(_First, _Last);
}
#endif /* _HAS_STRICT_CONFORMANCE */
mapped_type& operator[](const key_type& _Keyval)
{ // find element matching _Keyval or insert with default mapped
iterator _Where = this->lower_bound(_Keyval);
if (_Where == this->end()
|| this->comp(_Keyval, this->_Key(_Where._Mynode())))
_Where = this->insert(_Where,
value_type(_Keyval, mapped_type()));
return ((*_Where).second);
}
};
less的定義
template<class _Ty>
struct less
: public binary_function<_Ty, _Ty, bool>
{ // functor for operator<
bool operator()(const _Ty& _Left, const _Ty& _Right) const
{ // apply operator< to operands
return (_Left < _Right);
}
};
從上面定義可以看出,map<_Kty, _Ty, _Pr, _Alloc>的後兩個默認的參數,class _Pr = less<_Kty> , class _Alloc = allocator<pair<const _Kty, _Ty> > >;
而默認缺省定義map時,此時如果結構體為key值時,而此時class _Pr = less<_Kty>要進行_Left < _Right,而如果此時結構體沒有<方法時,則會出錯。
解決上面問題有兩種方法:1.在結構體重重載<操作符;2.定義自己的排序函數,顯式調用。
1.結構體中重載<
#include <iostream>
#include <string>
#include <map>
using namespace std;
struct StructTest
{
string sTemp;
int nCount;
bool operator<(const StructTest& test) const
{
if (sTemp < test.sTemp)
{
return true;
}
else if (sTemp == test.sTemp)
{
if (nCount < test.nCount)
return true;
else
return false;
}
else
{
return false;
}
}
};
void main()
{
map<StructTest,string>mapTest;
map<StructTest,string>::iterator mapTestiter;
StructTest StructTest1,StructTest2,StructTest3;
StructTest1.sTemp="111111";
StructTest1.nCount=6;
StructTest2.sTemp="111111";
StructTest2.nCount=7;
StructTest3.sTemp="000000";
StructTest3.nCount=6;
mapTest.insert(make_pair(StructTest1,"1"));
mapTest.insert(make_pair(StructTest2,"2"));
mapTest.insert(make_pair(StructTest3,"3"));
for (mapTestiter=mapTest.begin();mapTestiter!=mapTest.end();mapTestiter++)
{
cout<<(mapTestiter->first).sTemp<<" "<<(mapTestiter->first).nCount<<" "<<mapTestiter->second<<endl;
}
}
#include <iostream>
#include <string>
#include <map>
using namespace std;
struct StructTest
{
string sTemp;
int nCount;
};
struct ptr_less : public binary_function<StructTest,StructTest,bool>
{
bool operator()(const StructTest& test1, const StructTest& test2) const
{
if (test1.sTemp < test2.sTemp)
{
return true;
}
else if (test1.sTemp == test2.sTemp)
{
if (test1.nCount < test2.nCount)
return true;
else
return false;
}
else
{
return false;
}
}
};
void main()
{
map<StructTest,string,ptr_less>mapTest;
map<StructTest,string,ptr_less>::iterator mapTestiter;
StructTest StructTest1,StructTest2,StructTest3;
StructTest1.sTemp="111111";
StructTest1.nCount=6;
StructTest2.sTemp="111111";
StructTest2.nCount=7;
StructTest3.sTemp="000000";
StructTest3.nCount=6;
mapTest.insert(make_pair(StructTest1,"1"));
mapTest.insert(make_pair(StructTest2,"2"));
mapTest.insert(make_pair(StructTest3,"3"));
for (mapTestiter=mapTest.begin();mapTestiter!=mapTest.end();mapTestiter++)
{
cout<<(mapTestiter->first).sTemp<<" "<<(mapTestiter->first).nCount<<" "<<mapTestiter->second<<endl;
}
}

當然其中的find方法也與_Pr有關。
map中find調用紅黑樹的find
具體調用如下:1.map中的find

2.紅黑樹中find

注意:STL中的SET與map一樣。
具體調用可以查看STL源碼剖析、或者vs中查看相關定義