我有一個std :: vector中的元素集合,它們從第一個元素開始按降序排列。我必須使用矢量,因爲我需要將這些元素放在連續的內存塊中。我有一個集合,它擁有許多具有描述特徵的向量實例(總是按降序排列)。vector :: erase and reverse_iterator
現在,有時候,當我發現我有更大的集合(持有這些載體之一),我丟棄這些載體某種方式與此類似僞代碼的最小元素元素過多:
grand_collection: collection that holds these vectors
T: type argument of my vector
C: the type that is a member of T, that participates in the < comparison (this is what sorts data before they hit any of the vectors).
std::map<C, std::pair<T::const_reverse_iterator, std::vector<T>&>> what_to_delete;
iterate(it = grand_collection.begin() -> grand_collection.end())
{
iterate(vect_rit = it->rbegin() -> it->rend())
{
// ...
what_to_delete <- (vect_rit->C, pair(vect_rit, *it))
if (what_to_delete.size() > threshold)
what_to_delete.erase(what_to_delete.begin());
// ...
}
}
現在,運行此代碼後,在what_to_delete
我有一個迭代器集合指向我想從這些向量(整體最小值)中刪除的原始向量。請記住,他們打這個代碼,這意味着對於任何what_to_delete[0 - n]
沒有辦法上n - m
位置的迭代器將進一步指向的元素由相同的矢量的開始比n
,其中m > 0
之前的原始矢量進行排序。
當從原始向量中刪除元素時,我必須將reverse_iterator轉換爲迭代器。要做到這一點,我靠C++ 11的§24.4.1/ 1:
reverse_iterator的和迭代器之間的關係是 & *(reverse_iterator的(I))== & *(I-1)
這意味着刪除vect_rit
,我使用:
vector.erase(--vect_rit.base());
現在,根據C++ 11標準§23.3.6.5/3
:
迭代器擦除(const_iterator位置);效果:在擦除點處或之後使迭代器和引用無效 。
這是如何與reverse_iterators協同工作的?是否在內部實現了reverse_iterator,並引用了矢量的真實開始(vector[0]
)並將該vect_rit轉換爲經典迭代器,然後擦除將是安全的?或者根本reverse_iterator的使用rbegin()(這是vector[vector.size()]
)作爲參考點,並刪除任何進一步的距離向量的0指數仍然會失效我的反向迭代器?
編輯:
貌似reverse_iterator的使用rbegin()作爲它的基準點。按照我描述的方式擦除元素在第一個元素被刪除後給我提供了有關不可引用的迭代器的錯誤。而當存儲經典迭代器(轉換爲const_iterator
),而插入到what_to_delete
正常工作。
現在,以供將來參考,不標準規定什麼應該在隨機存取reverse_iterator的情況下的參考點來處理?或者這是一個實現細節?
謝謝!
是關於標準的字母或關於常見實現的問題? – Managu 2012-07-15 07:32:59
@Managu - 兩者。 – 2012-07-15 07:36:26
據我所知,你沒有/想在這裏使用'reverse_iterator'。 'std :: vector'具有隨機訪問迭代器,這意味着您可以使用從'.end()'開始的常規'iterator'並將其向後移動。這樣,你不需要用太多的魔法來使用'.erase()'。 – 2012-07-15 08:20:32