C++裡為何要定義類似size_type,difference_type,iterator這種型別?匿名使用者2020-05-08 13:56:42

更新:評論區有後續。

這是一個可以無限扯皮的問題。

size_type

VS

unsigned

沒什麼好說的,

unsigned

太小了。

我給你模擬一下,如果要是在 C++ 群討論

size_type

VS

size_t

會是什麼樣的情況。

Alice:

size_t s = v。size()

Bob:@Alice 太菜了,容器的

v。size()

返回

size_type

,不是

size_t

Alice:有區別?

size_type

不就定義成

size_t

嗎?

Bob:不,這是 implementation defined 。

Alice:不是,你知道

size_t

是啥嗎?

size_t

sizeof

的返回值,是一次能分配的最大記憶體。容器的 size 肯定小於等於

size_t

Bob:還是 naive 。如果容器是非連續的,例如

std::list

,容器的 size 當然可以超過

size_t

Alice:@Bob 我這是 v ,看命名是 vector 。就算是

std::list

,32 位的

size_t

是 32 位的,64 位的

size_t

是 64 位的,能給你用的最大記憶體就是 2^64,怎麼可能超越?

Cara:有人玩吃雞嗎?

Bob:16 位的呢?

Alice:16 位怎麼了?

Bob:16 位的

size_t

是 16 位的,但是別忘了 DOS 是分段的。20 位地址線,

std::list

的 size 當然可以大於

size_t

。至少不能低於 20 位。只要是分段的體系結構都存在這個問題。

Alice:現在還有分段?

Ela:一個程序可以跨越 segment 使用所有 20 位記憶體嗎?

Alice:不是,你都真實模式了,說個 JB 呢?

Bob:我就舉個例子,現在 IBM 好像也有分段的。

Cara:有人玩吃雞嗎?

C++裡為何要定義類似size_type,difference_type,iterator這種型別?知乎使用者6DZ4212020-05-08 21:08:27

看下這本書吧,都是抽象,抽象再抽象

C++裡為何要定義類似size_type,difference_type,iterator這種型別?

C++裡為何要定義類似size_type,difference_type,iterator這種型別?Star.E2020-05-09 18:18:04

首先,size_t和平臺有關,比如x86、x64。需要儘量符合平臺記憶體大小,但又不會太大以至浪費。

2。 其次,容器定義不同size_type是有實際用途的。

比如boost::container::vector,可以用模板引數選擇用size_t還是uint32_t,甚至uint8_t也是可以的。這樣可以縮小容器本身的記憶體駐留(memory footprint)。

如果寫程式碼時,已經把size_type考慮在內,那麼就可以用boost::container::vector無縫替換std::vector。

3。 difference_type有符號,常用來表示記憶體地址之間的距離(std::distance)。因為size_type一般無符號,所以difference_type可能比size_type大。比如記憶體地址上限是4G,理論上用int32_t是無法表示所有distance的,需要int64_t。實踐上可能用int32_t混過去了,32位的windows程式通常記憶體不能超過2g,我覺得和這個是有關係的。

4。 iterator是c++的標誌性設計,解耦了容器與演算法。iterator實現五花八門,最簡單的是記憶體指標,複雜的可以很複雜,比如boost::adjacency_list的edge iterator。功能是int完全不能比擬的。

5。 對於size_t,signed vs unsigned是個非常深奧的問題。實踐上size_t用signed非常好,不存在signed vs unsigned比較,統一了size_type與difference_type,減少了很多index減法bug。但是size這個東西,概念/本質上是非負的,用signed影響閱讀理解。而程式是給人讀的,降低心智負擔/

無歧義

很重要。c++選擇了unsigned,態度就是

概念

比實踐更重要。c++一直受此詛咒,concept陰魂不散。

總之c++是個隨心所欲的語言,為了滿足這種隨心所欲,代價就是基礎設施的異常複雜。

C++裡為何要定義類似size_type,difference_type,iterator這種型別?暮無井見鈴2020-05-09 23:10:28

我的角度可能有點奇怪。

C++ 標準庫工具需要定義這些巢狀型別,一定程度上是由於當初設計 STL 時( 1994 年開始)沒有

decltype

,從而泛型程式碼需要依賴顯式寫出來的巢狀型別名。

本來

我們不需要巢狀的

size_type

,只需要拿

size

函式的返回型別;

我們不需要巢狀的

iterator

,只需要拿

begin

函式的返回型別;

……

不過

difference_type

對於不能相減(一般是非隨機訪問)的迭代器還是有意義的。

至於

int

unsigned

為什麼有時不適合,可以參考別人的回答。

C++裡為何要定義類似size_type,difference_type,iterator這種型別?pansz2020-05-10 10:32:28

這個問題簡單,你說的那幾個型別都是 64 位的,int 跟 unsigned 一般是 32 位的,放 64 位資料進去會崩。

早年間習慣把pointer或者size放進int的史前程式設計師,它們留下的程式碼在後世基本都炸了,BOOM得不要不要的。

而且把64位放進32位的這種操作在特定情況下不會立刻崩,假如被覆蓋的部分恰好可寫的話,你會在另外一個莫名其妙的場合發現莫名其妙的bug。

別問我為什麼知道,這就是我幫史前程式設計師收拾殘局的親身經歷。