c++ 中,set、map、multiset、multimap 都是使用 rb-tree 作為底層資料結構的,所以他們的**其實就是封裝了一層的紅黑樹區別在於:
這篇部落格要記錄的是關於 map 的下標操作符的東西,從下邊**可以看出:
1、map 的 既可以作為左值引用(即內容可以被修改),又可以作為右值引用(即內容不可以被修改);
2、mapmmp; mmp[「hello」] 輸出 0,說明預設都是 0,這樣就可以按照很常見的寫法直接 ++mmp[「hello」] 了,完全不需要管 「hello」 是否存在;
3、輸出 mm[「hello」] 為 0 後,發現 map 中已經插入了 'hello"。
mapint> mmp;
if(mmp.
find
("hello"
)!= mmp.
end())
// 沒找到
cout <<
"found"
<< endl;
cout << mmp[
"hello"
]<< endl;
// 0
if(mmp.
find
("hello"
)!= mmp.
end())
// 找到
cout <<
"found"
<< endl;
++mmp[
"abc"];
cout << mmp[
"abc"
]<< endl;
// 1
這些都是因為 map 的下標操作符對左值、右值都適用,這關鍵就在於,map 的 返回值採用的是 by reference 傳遞形式,如下:
// class template map
template
<
class
_kty
,// 鍵值
class
_ty,
// 實值
class
_pr= less<_kty>
,// 比較函式
class
_alloc
= allocatorconst _kty, _ty>>
>
// 儲存結構,注意const
class
map:
public _tree<_tmap_traits<_kty, _ty, _pr, _alloc,
false
>>
這是 c++ 11 之後的寫法,用到了 emplace 和 std::move(移動語義),可能不是很好理解,看《劍指offer》上寫的更好理解一點:
template
<
class
key,
classt,
class
compare
= less
,class
alloc
= alloc>
class
map}
;
這個返回值看起來很複雜,但是理解起來簡單些,首先就是一直沒有變的by reference形式的返回型別,在傳入引數中,因為沒有用到移動語義,所以不需要上邊的 &&,而是單純的const reference形式。對於 return 這一句,首先是用傳入的鍵值和臨時物件 t() 建立乙個臨時 value_type(也就是 pair),然後將這個 pair 插入到 map 中,要注意,這個 insert 如果插入的鍵值在 map 中沒有,就插入到合適位置並返回,如果已經存在,就直接返回已經存在的。要注意,這裡 insert 呼叫的是紅黑樹的 insert_uniquem,實際返回的是乙個 pair (如下是 insert_unique 的乙個返回路徑),first 是迭代器,second 是是否插入新值。
return pairbool
>
(j,false
);
所以 *(insert(value_type(k, t()))).first的目的就是獲取到這個迭代器,然後最後.second返回實值,下標操作符結束。
所以說,上邊的例子中,++mmp[「abc」]; 一句,其實是兩個操作,先用 int 預設的建構函式,建立乙個臨時 int,同於建立 pair,然後插入到 map中,這個臨時的 int 預設為 0,插入之後,執行 ++ 操作,對已經存在於 map 中的這個迭代器(剛建立的)的實值進行 ++。
c語言操作符 位操作符 移位操作符
1 按位操作符 1.1 按位 與 雙目運算子 僅當兩個運算元都為1時,結果為1,否則為0。參與運算的數以補碼方式出現。例 9 5 1 0000 1001 9的補碼 0000 0101 5的補碼 0000 0001 1的補碼 應用 a 通常將某些位清零或保留某些位。例如 將a的高八位清零,保留低八位,...
linq操作符 限定操作符
限定操作符運算返回乙個boolean值,該值指示序列中是否有一些元素滿足條件或者是否所有元素都滿足條件。一 all操作符 all方法用來確定是否序列中的所有元素都滿足條件。看下面的例子 1 using system 2using system.collections.generic 3using s...
C 中為類過載下標操作符(2 2)
當定義myclass類的常量物件時 const myclass c my class 5 2.1 返回值是引用型別 中提到的過載下標操作符的返回值是引用型別,因此當有如下 時不報錯。int i c my class 0 其報錯資訊為 error c2678 二進位制 沒有找到接受 const myc...