C++中std::distance 和 .size()的區(qū)別小結(jié)
在 C++ 中,std::distance
和 .size()
雖然都能獲取元素?cái)?shù)量,但二者的設(shè)計(jì)目的、適用場(chǎng)景和性能特性有顯著差異。以下是關(guān)鍵對(duì)比及使用建議:
?? ?一、核心區(qū)別?
?特性? | ?**std::distance(first, last)**? | ?**container.size()**? |
---|---|---|
?使用范圍? | 任意迭代器范圍(包括子范圍、非容器序列) | 僅限完整容器(begin() 到 end()) |
?時(shí)間復(fù)雜度? | 隨機(jī)訪問(wèn)迭代器:?O(1)?;非隨機(jī)訪問(wèn):?O(n)? | 隨機(jī)訪問(wèn)容器:?O(1)?;部分容器(如 std::list):?O(n)?? |
?實(shí)現(xiàn)原理? | 根據(jù)迭代器類(lèi)型動(dòng)態(tài)選擇(減法或遍歷) | 容器內(nèi)部計(jì)數(shù)器(或遍歷計(jì)算) |
?靈活性? | 可計(jì)算任意兩個(gè)迭代器的距離(如子區(qū)間) | 僅返回容器總元素?cái)?shù) |
?? 示例:計(jì)算子范圍長(zhǎng)度時(shí)只能用 distance
std::vector<int> vec{1, 2, 3, 4, 5}; auto start = vec.begin() + 1; // 指向 2 auto end = vec.end() - 1; // 指向 5 int len = std::distance(start, end); // 3(正確) int size = vec.size(); // 5(無(wú)法獲取子范圍)
? ?二、性能差異:何時(shí)優(yōu)先用.size()???
?隨機(jī)訪問(wèn)容器(如 std::vector)??
- ? ?**.size() 更高效?:直接讀取內(nèi)部計(jì)數(shù)器,時(shí)間復(fù)雜度 ?O(1)?**?。
- ? std::distance(begin(), end()) 雖也是 O(1),但多一次函數(shù)調(diào)用開(kāi)銷(xiāo)。
?非隨機(jī)訪問(wèn)容器(如 std::list, std::set)??
- ?? ?兩者性能可能相同?:
- std::list::size() 在部分實(shí)現(xiàn)中需遍歷鏈表(O(n)),與 std::distance 遍歷代價(jià)一致。
- 例如 GCC 的 std::list::size() 可能調(diào)用 std::distance 實(shí)現(xiàn)。
- ? ?建議用 empty() 替代?:若只需檢查容器是否為空,empty() 是 ?O(1)?? 且更安全。
- ?? ?兩者性能可能相同?:
?? ?三、必須用std::distance的場(chǎng)景?
?計(jì)算子范圍長(zhǎng)度?
auto mid = vec.begin() + 3; int sub_len = std::distance(vec.begin(), mid); // 3(前3個(gè)元素)[7,10](@ref)
?處理非容器序列(如數(shù)組、自定義迭代器)??
int arr[] = {10, 20, 30}; auto len = std::distance(std::begin(arr), std::end(arr)); // 3[3,9](@ref)
?泛型編程中兼容任意迭代器?
模板代碼需支持各種容器時(shí),distance
可統(tǒng)一處理:
template <typename Iter> void process(Iter start, Iter end) { int n = std::distance(start, end); // 兼容鏈表、向量等[5,8](@ref) // ... }
?四、總結(jié):選擇策略?
?場(chǎng)景? | ?推薦方法? | ?原因? |
---|---|---|
獲取完整容器元素總數(shù) | .size() | 語(yǔ)義清晰,可能更高效(O(1)) |
檢查容器是否為空 | .empty() | 絕對(duì) O(1),避免遍歷 |
計(jì)算子范圍、數(shù)組或泛型迭代器的距離 | std::distance | 唯一可行方案,靈活兼容 |
非隨機(jī)訪問(wèn)容器(如鏈表)的完整范圍長(zhǎng)度 | ?**均可,優(yōu)先 .size()**? | 性能相同,但 .size() 可讀性更佳 |
?? ?黃金法則?:
- 優(yōu)先用 .size() 獲取容器總大??;
- 涉及子范圍、泛型代碼或非容器序列時(shí),必須用 std::distance;
- 檢查是否為空時(shí),?**永遠(yuǎn)用 .empty() 而非 size() == 0**?。
到此這篇關(guān)于C++中std::distance 和 .size()的區(qū)別小結(jié)的文章就介紹到這了,更多相關(guān)C++ std::distance .size()內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
C++實(shí)現(xiàn)循環(huán)隊(duì)列和鏈?zhǔn)疥?duì)列的示例
下面小編就為大家分享一篇C++實(shí)現(xiàn)循環(huán)隊(duì)列和鏈?zhǔn)疥?duì)列的示例,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧2017-12-12深入探究C++中的容器適配器與仿函數(shù)技術(shù)
C++中的容器適配器和仿函數(shù)是實(shí)現(xiàn)數(shù)據(jù)結(jié)構(gòu)與算法的重要技術(shù),容器適配器可以將一個(gè)容器轉(zhuǎn)換為另一個(gè)形式,仿函數(shù)則可以自定義數(shù)據(jù)類(lèi)型的比較、排序、計(jì)算等行為,提高程序的靈活性和可重用性2023-04-04解讀構(gòu)造函數(shù)的調(diào)用規(guī)則、深拷貝與淺拷貝
本文主要介紹了C++中的默認(rèn)構(gòu)造函數(shù)、拷貝構(gòu)造函數(shù)以及深拷貝和淺拷貝的概念,并通過(guò)實(shí)際代碼示例進(jìn)行了詳細(xì)講解2024-11-11C語(yǔ)言課程設(shè)計(jì)之停車(chē)場(chǎng)管理問(wèn)題
這篇文章主要為大家詳細(xì)介紹了C語(yǔ)言課程設(shè)計(jì)之停車(chē)場(chǎng)管理問(wèn)題,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2022-03-03C++內(nèi)存泄漏檢測(cè)和解決方法小結(jié)
內(nèi)存泄露在編程中是常見(jiàn)的一種問(wèn)題,一但程序發(fā)生內(nèi)存泄露問(wèn)題,將導(dǎo)致程序崩潰無(wú)法運(yùn)行,內(nèi)存泄漏是指程序在運(yùn)行過(guò)程中,由于疏忽或錯(cuò)誤導(dǎo)致已分配的內(nèi)存空間無(wú)法被正確釋放,本文給大家就介紹了C++中內(nèi)存泄漏如何檢測(cè)和解決,需要的朋友可以參考下2025-01-01C++高級(jí)數(shù)據(jù)結(jié)構(gòu)之二叉查找樹(shù)
這篇文章主要介紹了C++高級(jí)數(shù)據(jù)結(jié)構(gòu)之二叉查找樹(shù),文章圍繞主題展開(kāi)詳細(xì)的內(nèi)容介紹,具有一定的參考價(jià)值,需要的小伙伴可以參考一下2022-05-05詳解C++異常處理(try catch throw)完全攻略
這篇文章主要介紹了詳解C++異常處理(try catch throw)完全攻略,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2021-03-03C++ vector在多線程操作中出現(xiàn)內(nèi)存錯(cuò)誤問(wèn)題及解決
這篇文章主要介紹了C++ vector在多線程操作中出現(xiàn)內(nèi)存錯(cuò)誤問(wèn)題及解決方案,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2023-08-08