2015-03-30 39 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)'是用於非隨機訪問迭代昂貴。 –

相關問題