2010-11-04 102 views
5

只见用来从std::vector删除一个选择的元素下面的代码:迭代器是否支持+运算符?

vector<hgCoord>::iterator it; 
int iIndex = 0; 
    const int iSelected = 5; 
for(it = vecPoints.begin(); it != vecPoints.end(); ++it, ++iIndex) 
{ 
    if(iIndex == iSelected) 
    { 
     vecPoints.erase(it); 
     break; 
    } 
} 

我认为,这个代码是没有效率的,应该按如下方式写入:

vector<hgCoord>::iterator it; 
int iIndex = 0; 
    const int iSelected = 5; // we assume the vector has more than 5 elements. 

    vecPoints.erase(vecPoints.begin() + iSelected); 

不过,我不是确定此代码是否遵循C++ STL标准。

+0

你是对的,因为'std :: vector :: iterator'是一个'RandomAccessIterator'(又名'T *')。请记住,如果向量中的元素少于5个,则第二个算法将失败。 – 2010-11-04 19:12:53

+1

如果这些前缀''i'是匈牙利符号的一种形式,我强烈反对任何一段代码。 – 2010-11-04 19:30:13

+0

@ eq-:什么,因为'i'应该用作'iterator'的前缀,你的意思是;-p – 2010-11-04 19:54:13

回答

12

为了使代码通用的,所以它的作品无论是否迭代器支持operator +,并使用最有效的可用的执行:

template <typename C> 
void erase_at(C& container, typename C::size_type index) { 
    typename C::iterator i = container.begin(); 
    std::advance(i, index); 
    container.erase(i); 
} 

内部,std::advance使用operator +如果迭代器类型支持它。否则(例如,对于std::list<>::iterator),它将循环中的迭代器逐步推进一步,就像您发布的第一个代码一样。

+0

......... yup ..... +1 – 2010-11-04 19:41:54

+3

回复对dirbeas'已删除答案的评论 - 我认为'std :: advance'修改其参数的原因与事实有关因为它非常不依赖于类型,特别是它适用于所有的InputIterator,它们是*便宜*但*危险*拷贝。当与可能只是InputIterator的迭代器(不是ForwardIterator)一起使用时,不能再安全地使用旧值,因此即使它返回了迭代器,仍然只能将它用作'i = std ::提前(i,n);',或者像在dribeas'代码中一样临时。返回'无效'有助于防止愚蠢。有时。也许。 – 2010-11-04 19:49:06

+0

谢谢你的解释。 – q0987 2010-11-04 21:17:14

10

随机访问迭代器支持加法和减法,并且std::vector迭代器是随机访问。

2

你正确地认为:)

1

这应该工作的优良载体,因为向量迭代器是随机访问迭代器,所以没关系添加为你所做的偏移量。对于其他一些容器类型(如deque或map)也是如此。

因此,你的代码对于一个向量更好,但其他代码可能已经打算与其他类型的容器一起工作。

+0

实际上,'deque'也使用随机访问迭代器。 – 2010-11-04 19:56:38

+0

我认为修改过的代码适用于vector,string和deque。 – q0987 2010-11-04 21:16:46

+0

@Fred Larson:哎呀!我不知道我为什么输入deque,我的意思是列表!感谢您的更正。 – dajames 2010-11-16 13:41:26