Map以自定義類做為鍵值
map在STL中的定義
template <class Key, class T, class Compare = less<Key>, class Alloc = alloc>
第一個引數Key是關鍵字型別
第二個引數T是值型別
第三個引數Compare是比較函式(仿函式)
第四個引數是記憶體配置物件
map內部儲存機制實際是以紅黑樹為基礎,紅黑樹在插入節點時,必須依照大小比對之後在一個合適的位置上執行插入動作。所以作為關鍵字,起碼必須有“<”這個比較操作符。我們知道,int,float,enum,size_t等等簡單關鍵字,都有內建的比較函式,與map搭配無論是插入還是查詢,都沒什麼問題。但是作為複雜資料型別,如果沒有明確定義“<”比較操作符,就不能與map直接搭配使用,除非我們自己定義第三個引數。
在選擇map的關鍵字時,注意以下兩點,同時這兩點也是改錯的方法:
a) 關鍵字明確定義“<”比較操作符
b) 沒有“<”比較操作符,自定義仿函式替代第三個引數Compare,該仿函式實現“()”操作符,提供比較功能。插入時各節點順序以該仿函式為綱。
以std::pair為關鍵字摻入map
下面我們先寫一個有錯誤的函式,在分析錯誤原因之後,逐步進行修正。
#include <map>
int main()
{
std::map<std::pair<int, int>, int> res;
res.insert(std::make_pair(12,33), 33);
}
這個程式一定失敗,如果非要如此使用,上述a方法顯然不適合,std::pair是已定義好的結構體不可修改。只能使用b方法了,定義一個比較類改造如下:
以結構體或類為關鍵字插入map
編譯這個程式也是錯誤的,錯誤意思大概也是沒有定義“<”比較函式。因為struct st是我們自己定義的結構體,所以修改這個程式可以使用上面a、b兩種方法。我們先談第一種,第一次修改時我也搞錯了,我是這樣定義比較函式的。
按照這個改動再次編譯程式還是錯誤,有個如下這樣的提示:
/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
為什麼會出現這個 問題呢?我們深入STL的原始碼看下。既然說是/usr/include/c++/3.2.3/bits/stl_function.h的197行出了問題,且看這行是什麼。
193 /// One of the @link s20_3_3_comparisons comparison [email protected].
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呼叫這個比較符時,它都是以const方式傳入,不可能再以非const方式呼叫,故出錯。修正如下
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));}
以友聯函式代替函式內部定義的比較操作符,STL內部也多是以這種方式定義的。如果我非要以內部定義的方式呢?可以使用b方法,我們自定義一個比較仿函式,替代預設的less。
插入函式返回值
在map容器中插入資料有很多函式可用,這裡只討論最普通的insert操作,在STL中它是這樣定義的。
pair<iterator, bool> insert(const value_type& x);
map容器不允許鍵值重複,在執行插入操作後,可以憑藉該返回值獲取操作結果。返回值是一個迭代器和布林值的鍵值對,迭代器指向map中具有該值的元素,布林值表示是否插入成功。如果布林值為true,表示插入成功,則迭代器為新插入值在map中的位置;布林值為false,表示插入失敗(已經存在該值),迭代器為原有值在map中的位置。
相關推薦
Map以自定義類做為鍵值
map在STL中的定義 template <class Key, class T, class Compare = less<Key>, class Alloc = alloc> 第一個引數Key是關鍵字型別 第二個引數T是值型別 第三個引數Comp
C++ map以自定義資料型別做鍵值
struct Time { UINT16 nYear; UINT8 nMonth; UINT8 nDay; UINT8 nHour; UINT8 nMinute; UINT8 nSecond; UINT16 nTick; Time() { } Time(UINT16 nYear,UIN
【術】c#字典Dictionary自定義類作為key鍵
最近事情有點多,總是想直接貼程式碼,先放上去再說吧。 using UnityEngine; using System.Collections; using System.Collections.Generic; using System.Xml; usin
c++ map 使用自定義結構做關鍵字
map在STL中的定義 template <class Key, class T, class Compare = less<Key>, class Alloc = alloc> 第一個引數Key是關鍵字型別 第二個引數T是值型別 第三個引數Com
map以自定義型別當Key
關於map的定義: template < class Key, class T, class Compare = less<Key>, class Allocator = allocator<pair<const Key
java自定義類型 作為HashMap中的Key值 (Pair<V,K>為例)
由於 con als void hash system 進行 原型 自定義 由於是自定義類型,所以HashMap中的equals()函數和hashCode()函數都需要自定義覆蓋。 不然內容相同的對象對應的hashCode會不同,無法發揮算法的正常功能,覆蓋equals函
spring自定義類中@AutoWired標識的元素注入為null
最近在做專案的時候,發現程式執行的時候有一個nullpointer exception,一臉懵逼因為感覺程式沒什麼邏輯。後來發現是因為new出來的component不會自動注入它的元素。 現象:@Component修飾的自定義普通類中@Autowired屬性為null 原因:如果是通過new例項化的物件,
以自定義結構或類作為訊號和槽的引數
在QT中如何用自定義結構作為訊號和槽的引數,在網上查了一通,用人說要用qRegisterMetaType註冊結構,還有說要為結構使用巨集Q_DECLARE_METATYPE。不知道是不是他們的版本太舊。經本人驗證,既無需註冊,也無需使用巨集,就可使用結構或類作
【Qt】以QMap作為自定義類的靜態資料
類的公共資料有幾種儲存方式,其中一種為把資料作為一個類的靜態變數,這樣類的所有物件都可以訪問該資料,並且這個共享的資料只佔有在類的公共空間,不會因為物件的多少而增加儲存空間。 例如: sutudent.h class Student { public: stati
怎樣為std::map的自定義key提供比較操作(一)
stl的關聯容器(map,set)的key一般要求提供 < 比較操作。假設我們有一個結構SomeKey: struct SomeKey { int a, b; }; 要想以SomeKey作為std::map的key,需要為這個結構提
為AndroidStudio設定自定義類註釋
我們在使用eclipse的時候,只要在類上面輸入/**再按enter,就會出現類註釋。 package com.demo; /** * * @author chenjunxu * */ pub
自定義類作為Map key的條件
一,大家通常會用HashMap存放資料,key一般用的是String,Integer這種基本資料型別,但是用自定義物件或者泛型作為key的情況會出現put進去get不到的情形,如下程式碼: public class MapKey { public static v
Java 用自定義類作為 HashMap 的鍵
1、Java 用自定義類作為 HashMap 的鍵需要重寫 hashCode ( ) 和 equals ( ) 兩個方法。 2、 HashMap 中的比較 key 是先求出 key 的 hashCode 值,比較其是否相等,若相等再通過 equals ( ) 比較其Key值 是否相等 ,
map中使用自定義類指標作為key
//先上程式碼 #pragma once //想用類作為key,必須過載<運算子 或者提供 //想用指標作為key,也是可以的,不過要自己提供仿函式 class CBase { public: explicit CBase(int a); ~CBase(void); private:
利用hashtable以類物件為鍵儲存值
class hello { public static void main(String[] args) throws ParseException { Hashtable<Animal, String> map = new Hashtable<>(); ma
python:自定義類中迭代行為的實現
#!/usr/bin/env python # -*- coding: utf-8 -*- # @author : cat # @date : 2017/6/23. class
【JavaDemo】使用Entry遍歷含自定義類的Map集合
含有自定義類的Map遍歷 Demo2 此Demo演示方法2:獲取鍵值對物件Entry,然後用Entry分別鍵獲取鍵和值。 Map含有自定義類Singer。 自定義類Singer
為LINQ實現自定義類的Distinct方法
如果在LINQ裡要使用自定義類的Distinct方法,如果預設的不管用,(大部分情況不管用),那麼就要自己實現。 根據MSDN建議 1)實現IEquatable<T>介面中的public bool Equals(T other),這個很簡單 但是這個很操蛋,根本
自定義標題欄右鍵菜單
mman size sub append pan prot base rri import 摘自:http://stackoverflow.com/questions/4615940/how-can-i-customize-the-system-menu-of-a-wind
ios 自定義鍵盤的return鍵以及鍵盤的其他一些屬性
variable 位置 arch ext ddr gin character 觸發 hone //初始化textfield並設置位置及大小 UITextField *text = [[UITextField alloc]initWithFrame:CGRectMake(20