:::info 水球軟體學院 Discord discussion: [link](https://discord.com/channels/937992003415838761/1119853624978313276) ::: ## 問題 如題,為了實作一個 LRU_Cache, 我使用 unordered_map um 來記錄新加入 list 尾端元素的 iterator, 但是我發現 um 內存放的 iterator 指向的數值卻會隨著其他元素被 push_back 時改變, 有辦法避免其他情況嗎? 補充:我使用 list.rbegin().base() 來定位位於 list 尾端的元素,這個方法是正確的嗎? ```cpp= #include <iostream> #include <list> #include <unordered_map> int main(int argc, char *argv[]) { std::unordered_map<int, std::list<int>::iterator> um; std::list<int> l; for (int i = 0; i < 6; i++) { l.push_back(i); // FIXME: Why l.rbegin().base() is changed ? um[i] = (l.rbegin().base()); } for (const auto &n : l) { std::cout << n << std::endl; } std::cout << "in um: " << std::endl; for (auto it = um.begin(); it != um.end(); it++) { std::cout << "key: " << it->first << " value: " << *it->second << " addr of iterator: " << &(it) << std::endl; } return 0; } ``` ```shell 0 1 2 3 4 5 in um: key: 5 value: 6 addr of iterator: 0x505518 key: 4 value: 6 addr of iterator: 0x505518 key: 3 value: 6 addr of iterator: 0x505518 key: 2 value: 6 addr of iterator: 0x505518 key: 1 value: 6 addr of iterator: 0x505518 key: 0 value: 6 addr of iterator: 0x505518 ``` 由 `@EqualKirby` 解答,以下是我整理出的內容 :::info 1. `l.rbegin().base()` 這個用法在你的context的確是錯的,但這個背後其實牽涉到 C++ 是怎麼做出 reverse iterator 的,這個我可以後面展開(雖然打字好累),修正的方法跟樓上說的一樣 2. 最後那個addr of iter,其實你印到的是local variable的address。你如果想要知道iterator指向的element的位址,要 ``&*iter`,如果你要觀察存的 list iterator 指到哪,那就還要存second 跟解引用以後再取位址 3. 為甚麼你的 code 會剛好冒出`value` 是 `6` ::: ## Iterator 的型態 根據 [Writing a custom iterator in modern C++](https://www.internalpointers.com/post/writing-custom-iterators-modern-cpp) 內的圖片 <img src=https://raw.githubusercontent.com/monocasual/internalpointers-files/master/2020/12/iterators/iterator-hierarchy.png></img> 所說, Modern C++ 有六種 Iterator, 分別是: :::info 1. Input Iterator Can scan the container forward only once, can't change the value it points to (read-only); 2. Output Iterator Can scan the container forward only once, can't read the value it points to (write-only); 3. Forward Iterator Can scan the container forward multiple times, can read and write the value it points to; 4. Bidirectional Iterator Same as previous one but can scan the container back and forth; 5. Random Access Iterator Same as previous one but can access the container also non-sequentially (i.e. by jumping around); 6. Contiguous Iterator ::: ### `std::list` 作為 container 時,iterator 的行為: ### `std::list` 作為 container 時,長度存放的位置: