2011-11-24 205 views
4

我有一个向量的迭代器传递给它的方法。 在这种方法中,我想一些元素加入到载体中,但我不知道是否只具有迭代STL向量,迭代器和插入(C++)

void GUIComponentText::AddAttributes(vector<GUIComponentAttribute*>::iterator begin, vector<GUIComponentAttribute*>::iterator end) 
{ 
    for (vector<GUIComponentAttribute*>::iterator i = begin; i != end; ++i) 
    { 
     GUIComponentAttribute &attrib = *(*i); 

     // Here are the GUIComponentAttribute objects analyzed - if an object of a 
     // special kind appears, I would like to add some elements to the vector 
    } 
} 

感谢 马库斯

回答

2

首先,您必须更改界面。给定两个迭代器, 没有办法返回到它们引用的容器;所以如果 要修改的容器,你必须引用传递给它, 即:

void GUIComponentText::AddAttributes(
     std::vector<GUIComponentAttribute*>& attributes) 
{ 
    for (std::vector<GUIComponentAttribute*>::iter = attributes.begin(); 
      iter != attributes.end(); 
      ++ iter) 
    { 
     // ... 
    } 
} 

已经这样做了:插入可以迭代器失效。所以它取决于您要插入的地方 。如果要在当前位置插入 位置:单个元素的std::vector<>::insert返回该元素的迭代器 ,该元素已插入元素之前,因此您可以将其分配给您的迭代器,调整(如有必要)并继续:

iter = attributes.insert(iter, newAttribute); 
++ iter; // Return to where we were... 

如果要追加(push_back),这个问题是一个比较复杂的; 你需要计算偏移,然后重建迭代器:

size_t offset = iter - attributes.begin(); 
attributes.push_back(nweAttribute); 
iter = attributes.begin() + offset; 

在这种情况下,它可能是简单的使用size_t[],而不是一个迭代器进行迭代。

+0

感谢您的详细解答,绝对有帮助。 (只是在这种情况下,不幸的是界面不可更改) –

4

在你展示的代码时,这是可能的,这不可能。尤其是因为在迭代它时,不应该向矢量添加/移除元素。

+0

谢谢,我几乎猜到了。 在这种情况下,目的是将组合的属性拆分为它们的部分,以便能够保留算法的其余部分。所以我会尽力找到一个解决方案 –

3

这是STL长期以来的设计“问题”。迭代器不允许修改它们正在迭代的底层序列的结构:即,您可以修改(有时)元素本身,但不能添加/移除元素。虽然InputIteratorOutputIterator在这方面有点特别......呜呜......

这实际上是erase/remove成语的原因:

vec.erase(std::remove_if(vec.begin(), vec.end(), predicate), vec.end()); 

所以,不,抱歉,实在没有办法实际上修改了矢量。

但是,如上所示,您可以完美地使用remove_if算法,并简单地返回有效范围的新结束......或者您可以要求整个向量开始。

正如Björn指出的那样,在迭代时修改序列结构是容易出错的。

0

在迭代它时,不可能将元素添加到矢量中。另外,你肯定不能用一对迭代器向矢量添加一个 - 你需要一个指向整个矢量对象的指针/引用。

您可以做的最好的方法是返回一个由调用函数添加的新组件向量。