2015-03-30 44 views
-4

删除一个向量元素第四元素需要以下代码:为什么删除元素时需要vector.begin()?

vector<int> v; 
.... 
.... 
v.erase(v.begin()+3); // Erase v[3], i.e. the 4th element 

我不知道为什么我们需要v.begin()部分。 这将是更好的只是写:

v.erase(3); // Erase v[3], i.e. the 4th element 

的开始()是向量中的一员,因此擦除方法也可以同样处理的那部分为我们,让我们的代码会更容易阅读,容易理解。

有可能是一个很好的理由,我想知道。 有人可以解释或链接一个解释? 谢谢。

+0

'std :: vector v = {2,3,1}; v.erase(3);' - 可读?将它与'std :: set

+4

@Poriferous +3给出第二个元素?你先生不能算。 – Borgleader

+0

@Kerrek SB:我不明白你的意思 - 对不起,但为什么是'的std ::向量 V = {2,3,1}; v.erase(v.begin()+ 3);'更具可读性?在这两种情况下,它的麻烦.. – 4386427

回答

2

如果这是你希望能够做到,这是很容易拿出一个函数模板(或者是一个模板函数?),将做到这有略有不同,但很可能足够相似语法:

#include <iostream> 
#include <ostream> 
#include <vector> 

template <typename T> 
void erase_at(T& container, size_t pos) 
{ 
    container.erase(container.begin() + pos); 
} 



using namespace std; 

int main() { 
    vector<int> v; 

    v.push_back(0); 
    v.push_back(1); 
    v.push_back(2); 
    v.push_back(3); 
    v.push_back(4); 
    v.push_back(5); 

    for (vector<int>::iterator i = v.begin(); i != v.end(); ++i) { 
     cout << *i << " "; 
    } 

    cout << endl; 

    erase_at(v, 3); // <-- instead of `v.erase(v.begin() + 3)` 

    for (vector<int>::iterator i = v.begin(); i != v.end(); ++i) { 
     cout << *i << " "; 
    } 

    cout << endl; 

    return 0; 
} 
+1

你可能想使用'std :: next(container。begin(),pos)'否则你的'erase_at'只能在vector上运行(可能还有一些自定义容器)。 –

+2

@BillLynch:它也适用于'deque'和'basic_string'。限制它随机访问容器可能是一件好事。 –

+0

@Michael Burr - 感谢您的代码示例。它激励我寻找更多的线。它把我带到了C++上的Stroustrup书籍(C++ 11,第四版)。 4.5.6节实际上都包含了我的问题和代码的答案,展示了如何摆脱繁琐的迭代器样式。代码与您的示例非常相似。谢谢。 – 4386427

0

由于vector.erase的接收迭代,但不是整数。 你可以看到,在文档http://www.cplusplus.com/reference/vector/vector/erase/

STL开发商,我认为,想使擦除所有容器泛型类的唯一接口(向量,列表等)

+0

这就是我的问题:为什么使用迭代器如此复杂。为什么标准没有提供一个擦除()来获取索引。 – 4386427

+0

@nielsen按索引擦除只能在矢量上高效实现。为什么他们需要制定具体的方法来载体,如果他们已经有一个独特的接口,所有其他类? –

0

据推测,这里的关键之一是为标准库容器创建一个统一的接口。

让我们看看std::set<T>,std::vector<T>std::list<T>。只有其中一种情况下,我们是否可以访问随机访问迭代器。在所有其他情况下,获得container.begin() + 3可能相对昂贵。特别是当用户可能已经有迭代器时,因为他们发现元素存在于对象中,并且他们想要将其删除。

+1

它可以在内部完成,如擦除(std :: next(begin(),3));.因此,是否存在随机访问迭代器或例如前向迭代器并不重要。 –

+0

@VladfromMoscow:该点是,'的std ::下(开始(),3)'是用于非随机访问迭代昂贵。 –

相关问题