map插入自定義對(duì)象總結(jié)
難道插入map還有什么講究嗎?我們且看map在STL中的定義方法:
template <class Key, class T, class Compare = less<Key>, class Alloc = alloc>
第一個(gè)參數(shù)Key是關(guān)鍵字類型
第二個(gè)參數(shù)T是值類型
第三個(gè)參數(shù)Compare是比較函數(shù)(仿函數(shù))
第四個(gè)參數(shù)是內(nèi)存配置對(duì)象
map內(nèi)部存儲(chǔ)機(jī)制實(shí)際是以紅黑樹為基礎(chǔ),紅黑樹在插入節(jié)點(diǎn)時(shí),必須依照大小比對(duì)之后在一個(gè)合適的位置上執(zhí)行插入動(dòng)作。所以作為關(guān)鍵字,起碼必須有“<”這個(gè)比較操作符。我們知道,int,float,enum,size_t等等簡(jiǎn)單關(guān)鍵字,都有內(nèi)置的比較函數(shù),與map搭配無論是插入還是查找,都沒什么問題。但是作為復(fù)雜數(shù)據(jù)類型,如果沒有明確定義“<”比較操作符,就不能與map直接搭配使用,除非我們自己定義第三個(gè)參數(shù)。
在選擇map的關(guān)鍵字時(shí),注意以下兩點(diǎn),同時(shí)這兩點(diǎn)也是改錯(cuò)的方法:
a) 關(guān)鍵字明確定義“<”比較操作符
b) 沒有“<”比較操作符,自定義仿函數(shù)替代第三個(gè)參數(shù)Compare,該仿函數(shù)實(shí)現(xiàn)“()”操作符,提供比較功能。插入時(shí)各節(jié)點(diǎn)順序以該仿函數(shù)為綱。
以std::pair為關(guān)鍵字摻入map
下面我們先寫一個(gè)有錯(cuò)誤的函數(shù),在分析錯(cuò)誤原因之后,逐步進(jìn)行修正。
#include <map>
int main()
{
std::map<std::pair<int, int>, int> res;
res.insert(std::make_pair(12,33), 33);
}
這個(gè)程序一定失敗,如果非要如此使用,上述a方法顯然不適合,std::pair是已定義好的結(jié)構(gòu)體不可修改。只能使用b方法了,定義一個(gè)比較類改造如下:
#include <map>
struct comp
{
typedef std::pair<int, int> value_type;
bool operator () (const value_type & ls, const value_type &rs)
{
return ls.first < rs.first || (ls.first == rs.first && ls.second < rs.second);
}
};
int main()
{
std::map<std::pair<int, int>, int, comp> res;
res.insert(std::make_pair(std::make_pair(12,33), 33));
res.insert(std::make_pair(std::make_pair(121,331), 331));
res.insert(std::make_pair(std::make_pair(122,332), 332));
std::map<std::pair<int, int>, int, comp>::iterator it = res.find(std::make_pair(121,331));
if (it == res.end())
printf("NULL"n");
else
printf("%d %d %d "n", it->first.first, it->first.second, it->second);
return 0;
}
以結(jié)構(gòu)體或類為關(guān)鍵字插入map
#include <map>
struct st
{
int a, b;
st():a(0), b(0){}
st(int x, int y):a(x), b(y){}
};
int main()
{
std::map<struct st, int> res;
res.insert(std::make_pair(st(1,2), 12));
res.insert(std::make_pair(st(30,4), 34));
res.insert(std::make_pair(st(5,6), 56));
std::map<struct st, int>::iterator it = res.find(st(30,4));
if (it == res.end())
printf("NULL"n");
else
printf("first:%d second:%d %d"n", it->first.a, it->first.b, it->second);
return 0;
}
編譯這個(gè)程序也是錯(cuò)誤的,錯(cuò)誤意思大概也是沒有定義“<”比較函數(shù)。因?yàn)閟truct st是我們自己定義的結(jié)構(gòu)體,所以修改這個(gè)程序可以使用上面a、b兩種方法。我們先談第一種,第一次修改時(shí)我也搞錯(cuò)了,我是這樣定義比較函數(shù)的。
struct st
{
int a, b;
st():a(0), b(0){}
st(int x, int y):a(x), b(y){}
bool operator < (const struct st &rs) {return (this->a < rs.a || (this->a == rs.a && this->b < rs.b));}
};
按照這個(gè)改動(dòng)再次編譯程序還是錯(cuò)誤,有個(gè)如下這樣的提示:
/usr/include/c++/3.2.3/bits/stl_function.h:197: passing `const st' as `this' argument of `bool st::operator<(const st&)' discards qualifiers
為什么會(huì)出現(xiàn)這個(gè)問題呢?我們深入STL的源代碼看下。既然說是/usr/include/c++/3.2.3/bits/stl_function.h的197行出了問題,且看這行是什么。
193 /// One of the @link s20_3_3_comparisons comparison functors@endlink.
194 template <class _Tp>
195 struct less : public binary_function<_Tp,_Tp,bool>
196 {
197 bool operator()(const _Tp& __x, const _Tp& __y) const { return __x < __y; }
198 };
struct st中的“<”在編譯后真正是什么樣子呢?大概是bool operator < (struct st &ls, const struct st &rs)。在less調(diào)用這個(gè)比較符時(shí),它都是以const方式傳入,不可能再以非const方式調(diào)用,故出錯(cuò)。修正如下:
struct st
{
int a, b;
st():a(0), b(0){}
st(int x, int y):a(x), b(y){}
friend bool operator < (const struct st &ls, const struct st &rs);
};
inline bool operator < (const struct st &ls, const struct st &rs)
{return (ls.a < rs.a || (ls.a == rs.a && ls.b < rs.b));}
以友聯(lián)函數(shù)代替函數(shù)內(nèi)部定義的比較操作符,STL內(nèi)部也多是以這種方式定義的。如果我非要以內(nèi)部定義的方式呢?可以使用b方法,我們自定義一個(gè)比較仿函數(shù),替代默認(rèn)的less。
插入函數(shù)返回值
在map容器中插入數(shù)據(jù)有很多函數(shù)可用,這里只討論最普通的insert操作,在STL中它是這樣定義的。
pair<iterator, bool> insert(const value_type& x);
map容器不允許鍵值重復(fù),在執(zhí)行插入操作后,可以憑借該返回值獲取操作結(jié)果。返回值是一個(gè)迭代器和布爾值的鍵值對(duì),迭代器指向map中具有該值的元素,布爾值表示是否插入成功。如果布爾值為true,表示插入成功,則迭代器為新插入值在map中的位置;布爾值為false,表示插入失?。ㄒ呀?jīng)存在該值),迭代器為原有值在map中的位置。
上一篇:內(nèi)聯(lián)函數(shù)inline與宏定義深入解析
欄 目:C語言
下一篇:va_list(),va_start(),va_arg(),va_end() 詳細(xì)解析
本文標(biāo)題:map插入自定義對(duì)象總結(jié)
本文地址:http://mengdiqiu.com.cn/a1/Cyuyan/4117.html
您可能感興趣的文章
- 01-10使用map實(shí)現(xiàn)單詞轉(zhuǎn)換的實(shí)例分析
- 01-10海量數(shù)據(jù)處理系列之:用C++實(shí)現(xiàn)Bitmap算法
- 01-10解析bitmap處理海量數(shù)據(jù)及其實(shí)現(xiàn)方法分析
- 01-10VC對(duì)自定義資源加密解密(AES)的詳解
- 01-10二叉搜索樹的插入與刪除(詳細(xì)解析)
- 01-10二叉查找樹的插入,刪除,查找
- 01-10大家注意vector, list, set, map成員函數(shù)erase
- 01-10vector與map的erase()函數(shù)詳細(xì)解析
- 01-10stl容器set,map,vector之erase用法與返回值詳細(xì)解析
- 01-10vector,map,list,queue的區(qū)別詳細(xì)解析


閱讀排行
- 1C語言 while語句的用法詳解
- 2java 實(shí)現(xiàn)簡(jiǎn)單圣誕樹的示例代碼(圣誕
- 3利用C語言實(shí)現(xiàn)“百馬百擔(dān)”問題方法
- 4C語言中計(jì)算正弦的相關(guān)函數(shù)總結(jié)
- 5c語言計(jì)算三角形面積代碼
- 6什么是 WSH(腳本宿主)的詳細(xì)解釋
- 7C++ 中隨機(jī)函數(shù)random函數(shù)的使用方法
- 8正則表達(dá)式匹配各種特殊字符
- 9C語言十進(jìn)制轉(zhuǎn)二進(jìn)制代碼實(shí)例
- 10C語言查找數(shù)組里數(shù)字重復(fù)次數(shù)的方法
本欄相關(guān)
- 04-02c語言函數(shù)調(diào)用后清空內(nèi)存 c語言調(diào)用
- 04-02func函數(shù)+在C語言 func函數(shù)在c語言中
- 04-02c語言的正則匹配函數(shù) c語言正則表達(dá)
- 04-02c語言用函數(shù)寫分段 用c語言表示分段
- 04-02c語言中對(duì)數(shù)函數(shù)的表達(dá)式 c語言中對(duì)
- 04-02c語言編寫函數(shù)冒泡排序 c語言冒泡排
- 04-02c語言沒有round函數(shù) round c語言
- 04-02c語言分段函數(shù)怎么求 用c語言求分段
- 04-02C語言中怎么打出三角函數(shù) c語言中怎
- 04-02c語言調(diào)用函數(shù)求fibo C語言調(diào)用函數(shù)求
隨機(jī)閱讀
- 08-05dedecms(織夢(mèng))副欄目數(shù)量限制代碼修改
- 01-10使用C語言求解撲克牌的順子及n個(gè)骰子
- 01-11ajax實(shí)現(xiàn)頁面的局部加載
- 01-10C#中split用法實(shí)例總結(jié)
- 01-11Mac OSX 打開原生自帶讀寫NTFS功能(圖文
- 08-05織夢(mèng)dedecms什么時(shí)候用欄目交叉功能?
- 04-02jquery與jsp,用jquery
- 01-10delphi制作wav文件的方法
- 08-05DEDE織夢(mèng)data目錄下的sessions文件夾有什
- 01-10SublimeText編譯C開發(fā)環(huán)境設(shè)置