【发布时间】:2017-03-10 21:24:11
【问题描述】:
如果我修改列表并且列表为空,则 std::list 的反向过去结束迭代器将失效。但是根据语言规范列表 push_back 应该对迭代器没有影响:
将给定的元素值附加到容器的末尾。 1) 新元素被初始化为值的副本。 2) 值被移动到新元素中。 没有迭代器或引用无效。
正如我在language spec 中注意到的那样。在下面列出示例,否则我会发现该行为。
//Add or replace an element using reverse iterator
void addOrReplaceRev(std::list<int>& list, int val)
{
auto rit = std::find(list.rbegin(), list.rend(), val);
list.push_back(val); //invalidates the rend() iterator, if list empty
if(rit != list.rend()) //remove if the value existed earlier
list.erase((++rit).base());
}
void addOrReplace(std::list<int>& list, int val)
{
auto rit = std::find(list.rbegin(), list.rend(), val);
bool shouldErase = rit != list.rend(); //save the result before modification
list.push_back(val);
if(shouldErase) //All good, as we use saved query result
list.erase((++rit).base());
}
int main()
{
std::list<int> mylist1;
std::list<int> mylist2 = {1,2,4,5};
addOrReplaceRev(mylist1, 3); //empty list messes up with rev iters
addOrReplaceRev(mylist2, 3); //non-empty lists are fine
printf("SIZES %d:%d\n", mylist1.size(), mylist2.size());
std::list<int> mylist3;
std::list<int> mylist4 = {1,2,4,5};
addOrReplace(mylist3, 3);//if results are saved
addOrReplace(mylist4, 3);
printf("SIZES %d:%d\n", mylist3.size(), mylist4.size());
}
程序的输出是
SIZES 0:5
SIZES 1:5
注意:当我使用正向/常规迭代器时,我看不到这种行为。我正在使用 gcc 4.9.2 编译器。这是预期的还是编译器错误。
`
【问题讨论】:
-
尽管名称中有“iterator”,但保证适用于容器的迭代器不一定适用于其反向迭代器。