这个迭代器代码中发生了什么?

时间:2014-01-12 16:25:14

标签: c++ iterator

我对以下两个迭代器在下面的代码中指出的内容感到非常困惑。

list<fieldT>::iterator steeperField = currentField;
list<fieldT>::iterator shallowerField = 
   activeFields.insert(currentField, *currentField);

如果我们假设activeFields(这些迭代器所属的列表)有索引0,1,2(count = 3),并且currentField目前指向1.然后我想:

  1. steeperField设置为索引1。
  2. 将fieldT插入索引1的列表中,并返回从索引1开始的迭代器。
  3. 因此,steeperField应该指向与shallowField相同的位置。这 not 似乎正在发生的事情:shallowerField似乎指向索引2.为什么?

    <小时/> activeFields是作为list<fieldT> & activeFields传递的参数。 currentField是作为list<fieldT>::iterator & currentField传递的参数。 currentField最初是通过致电currentField = activeFields.begin();启动的。

2 个答案:

答案 0 :(得分:4)

当我简化程序时,I get the results I expect(没有断言失败):

#include <list>
#include <iostream>
#include <cassert>

using std::list;

std::ostream& operator<<(std::ostream& os, const list<char>& l)
{
    os << '{';
    for (auto el : l)
        os << el << ',';
    os << '}';

    return os;
}

int main()
{
    list<char> l{'a', 'b', 'c'};
    list<char>::iterator insertAt { std::next(std::begin(l)) }; // 'b'

    std::cout << l << '\n';

    list<char>::iterator newEl { l.insert(insertAt, 'd') };

    std::cout << l << '\n';

    assert(std::distance(std::begin(l), insertAt) == 2);
    assert(std::distance(std::begin(l), newEl)    == 1);
}

这让我相信我在你的问题中遗漏了一些东西,所以我制定了as in this post并推断出你问题中的问题:

  

因此,steeperField应该指向与shallowField相同的位置。

不,不应该。 steeperField是由一个人向右洗牌的旧元素; shallowField是你的新元素。 迭代器不是固定索引到容器中;它们链接到元素。在链表中,这意味着当您在元素之前插入新元素时,跟随元素。

  

这似乎不是正在发生的事情:shallowerField似乎指向索引2.为什么?

没有。 shallowerField指向索引1,应该如此。 steeperField指向索引2,也应该如此。

总之,在您进行测量时出现了问题

答案 1 :(得分:1)

首先让我们讨论一下函数声明

iterator insert(const_iterator position, const T& x);

它在迭代器位置之前插入元素x,并返回引用插入元素的迭代器。

在你的示例中,currentField;是一个迭代器,它引用列表中的某个元素。 * currentField是元素的值。现在

activeFields.insert(currentField, *currentField)

插入与currentField引用的元素值相同的值;在此元素之前。实际上,它将值传播到相对于currentField的左侧;。

如果我们假设currentField对应于列表{0,1,2}中的索引1,则在操作之后,列表将显示为{0,1,1,2},迭代器shallowerField将引用第一个1它将对应于索引1。

至于你的陈述

  

这似乎不是正在发生的事情:shallowerField似乎   指向索引2.为什么?

然后正确的答案是“似乎”,这似乎只是你。您应该显示一个简单的编译示例来演示这种情况。

这是一个例子

std::list<int> l = { 0, 1, 2 };

std::list<int>::const_iterator position = std::next( l.cbegin() );

std::cout << std::distance( l.cbegin(), position ) << std::endl;

std::list<int>::iterator result = l.insert( position, *position );

std::cout << std::distance( l.begin(), result ) << std::endl;

输出

1
1