STL map、set中key为结构体的用法

下面是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;

    }



}

截图20141203133228

2.定义自己的排序函数,显式调用

#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;

    }



}

截图20141203133749

当然其中的find方法也与_Pr有关。

map中find调用红黑树的find

具体调用如下:1.map中的find

截图20141203134531

2.红黑树中find

20141203134944

注意:STL中的SET与map一样。
具体调用可以查看STL源码剖析、或者vs中查看相关定义

你可能感兴趣的:(map)