程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> C語言 >> C++ >> C++入門知識 >> C++之Effective STL學習筆記Item21

C++之Effective STL學習筆記Item21

編輯:C++入門知識

好了,先貼一段英文,真心不想翻譯過來,而且感覺也翻譯不到那麼到位:

The STL is awash in comparisons of objects to see if they have the same value. For example, when you ask find to locate the first object in a range with a particular value, find has to be able to compare two objects to see if the value of one is the same as the value of the other. Similarly, when you attempt to insert a new element into a set, set::insert has to be able to determine whether that element’s value is already in the set.

The find algorithm and set’s insert member function are representative of many functions that must determine whether two values are the same. Yet they do it in different ways. find’s definition of “the same” is equality, which is based on operator==. set::insert’s definition of “the same” is equivalence, which is usually based on operator<.

Operationally, the notion of equality is based on operator==. If the expression “x == y” returns true, x and y have equal values, otherwise they don’t.

x and y have equivalent values with respect to operator< if the following expression is true:

!(x < y) && !(y < x)

 好了,關於等價和等值的討論,我們先到此為止。我們引入下一話題,假設我們現在創建如下一個set:

<, less_equal<> > s; 

向其中插入10:

s.insert();

然後再向其插入10,我們知道,set中的元素是沒有重復的,所以程序會判斷10是否已經在當前set中,為了方便說明,我們把第一個插入的10稱為10A,第二個稱為10B。set的判斷過程會是10A和10B是否是一樣的,set所定義的一樣就是我們之前提到的equivalence

那麼程序中的less_equal是怎麼來判斷的呢?我們根據上面的推導,一個合理的推導,set可能是這樣來判斷的:

!(10A <= 10B) && !(10B <= 10A)      

當然上頭的判定的結果為:!(true) && !(true) ,等價於 false && false,所以最終的結果會是false,也就是說,判定結果告訴我們,10A和10B is not equivalent!然後10B,也就是10會被再一次插入到set中,oh, no!

好了,這只是個玩笑,set可不會弱到如此地步,set中是不會存在重復元素的。小伙伴們肯定覺得疑惑了,這說了半天有毛用啊,set又不會使用less_equal這樣的順序,因為壓根就不允許equal的情況發生,你這不是找別扭呢嘛!

別急,set有不重復這個特性,那麼要是是個multiset呢,按照這個思路,這樣的操作一定會成功,會認為是兩個不同的元素插入到multiset內部,假設我們在後面需要做equal_range的相關操作(it identifies a range of equivalent values),問題就大了!

哈哈,和大家開了個很大的玩笑,STL是經過千錘百煉的,怎麼可能存在這樣傻的問題!關於這個問題SGI是最權威的了,我們可以去SGI查查,看到底是怎麼回事!還真有,關鍵字:Strict Weak Ordering,好了讓我們看看是怎麼解決這個問題的:

這段代碼編譯通過,但是執行時會報assert錯誤!我沒有搞清楚其中的原理,繼續研究吧!

好了,繞了這麼一大圈,其實就是想告訴你,在實現自己的類似less_equal仿函數的時候,一定要留神了,千萬不要存在這樣的bug!

感謝大家的閱讀,希望能幫到大家!

Published by Windows Live Writer.

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