我有一个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