[英]Why using `std::reverse_iterator` doesn't invoke UB?
我今天正在使用std::reverse_iterator
,並且正在考慮如何使用在容器上調用begin
創建的值。 根據cppreference ,如果我有從iterator i
構造的reverse_iterator r
,則以下必須保持&*r == &*(i-1)
。
但是,這意味着如果我寫這個
std::vector<int> vec = {1, 2, 3, 4, 5};
auto iter = std::make_reverse_iterator(begin(vec));
iter現在指向begin(vec)
之前放置的內存begin(vec)
,這是超出范圍的。 通過嚴格解釋C ++標准,這將調用UB。
(指針/迭代器有一個特定的規定,指向數組的1-last-the-end-end,但據我所知,沒有指針/迭代器到數組1的數字開頭。)
所以,我讀錯了鏈接 ,或者這個案例的標准中是否有特定的規定,或者當使用reverse_iterator
,整個數組被視為反轉,因此,指向數組前面的指針實際上是指針過去到底?
是的,你讀錯了。
反向迭代器不需要存儲指向元素開始之前的指針。
為了說明,采用2個元素的數組:
int a[2];
這些是前向迭代器:
a+0 a+1 a+2 // The last one is not dereferenceable
反向迭代器將以相反的順序用這些完全相同的值表示:
a+2 a+1 a+0 // The last one cannot be dereferenced
因此,雖然解除引用正常的迭代器非常簡單,但反向迭代器取消引用稍微復雜一些: pointer[-1]
(這是隨機訪問迭代器,其他更糟糕的是: It copy = pointer; --copy; return *copy;
)。
請注意,使用forward-iterator比反向迭代器更常見,因此前者比后者更有可能為它們優化代碼。 然而,由於所有轉換都是一個不錯的優化編譯器,但是沒有碰到那個角落的通用代碼很可能在任何一種類型下運行得更好。
std::make_reverse_iterator(begin(vec))
不可解除引用,與end(vec)
不可解除引用的方式相同。 它沒有“指向”任何有效的對象,這沒關系。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.