程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> C語言 >> C++ >> C++入門知識 >> STL map、set中key為結構體的用法,stlmap

STL map、set中key為結構體的用法,stlmap

編輯:C++入門知識

STL map、set中key為結構體的用法,stlmap


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

截圖20141203133749

當然其中的find方法也與_Pr有關。

map中find調用紅黑樹的find

具體調用如下:1.map中的find

截圖20141203134531

2.紅黑樹中find

20141203134944

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

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved