刪除元素

刪除最後一個元素:

std::vector<int> v{ 1, 2, 3 };
v.pop_back();                           // v becomes {1, 2}

刪除所有元素:

std::vector<int> v{ 1, 2, 3 };
v.clear();                              // v becomes an empty vector

按索引刪除元素:

std::vector<int> v{ 1, 2, 3, 4, 5, 6 };
v.erase(v.begin() + 3);                 // v becomes {1, 2, 3, 5, 6}

注意: 對於 vector 刪除不是最後一個元素的元素,必須複製或移動刪除元素之外的所有元素以填補空白。

刪除範圍中的所有元素:

std::vector<int> v{ 1, 2, 3, 4, 5, 6 };
v.erase(v.begin() + 1, v.begin() + 5);  // v becomes {1, 6}

注意: 上述方法不會改變向量的容量,只會改變大小。請參見向量大小和容量

刪除一系列元素的 erase 方法通常用作擦除 - 移除 習語的一部分。也就是說,首先 std::remove 將一些元素移動到向量的末尾,然後 erase 將它們關閉。對於小於向量的最後一個索引的任何索引,這是相對低效的操作,因為必須將擦除段之後的所有元素重新定位到新位置。對於需要有效刪除容器中任意元素的速度關鍵應用程式,請參閱 std::list

按值刪除元素:

std::vector<int> v{ 1, 1, 2, 2, 3, 3 };
int value_to_remove = 2;
v.erase(std::remove(v.begin(), v.end(), value_to_remove), v.end()); // v becomes {1, 1, 3, 3}

按條件刪除元素:

// std::remove_if needs a function, that takes a vector element as argument and returns true, 
// if the element shall be removed
bool _predicate(const int& element) {
    return (element > 3); // This will cause all elements to be deleted that are larger than 3
}
...
std::vector<int> v{ 1, 2, 3, 4, 5, 6 };
v.erase(std::remove_if(v.begin(), v.end(), _predicate), v.end()); // v becomes {1, 2, 3}

通過 lambda 刪除元素,而不建立其他謂詞函式

Version => C++ 11
std::vector<int> v{ 1, 2, 3, 4, 5, 6 };
v.erase(std::remove_if(v.begin(), v.end(),
     [](auto& element){return element > 3;} ), v.end()
);

從迴圈中按條件刪除元素:

std::vector<int> v{ 1, 2, 3, 4, 5, 6 };
std::vector<int>::iterator it = v.begin();
while (it != v.end()) {
    if (condition)
        it = v.erase(it); // after erasing, 'it' will be set to the next element in v
    else
        ++it;             // manually set 'it' to the next element in v
}

雖然重要的是不要在刪除時增加 it,但是在迴圈中重複擦除時應考慮使用不同的方法。考慮 remove_if 以獲得更有效的方式。

從反向迴圈中按條件刪除元素:

std::vector<int> v{ -1, 0, 1, 2, 3, 4, 5, 6 };
typedef std::vector<int>::reverse_iterator rev_itr;
rev_itr it = v.rbegin();

while (it != v.rend()) { // after the loop only '0' will be in v
    int value = *it;
    if (value) {
        ++it;
        // See explanation below for the following line.
        it = rev_itr(v.erase(it.base()));
    } else
        ++it;
}

請注意前一個迴圈的一些要點:

  • 給定一個指向某個元素的反向迭代器 it,方法 base 給出了指向同一元素的常規(非反向)迭代器。

  • vector::erase(iterator) 擦除迭代器指向的元素,並將迭代器返回給定元素後面的元素。

  • reverse_iterator::reverse_iterator(iterator) 從迭代器構造一個反向迭代器。

總而言之,線 it = rev_itr(v.erase(it.base())) 說:取反向迭代器 it,讓 v 擦除其常規迭代器指向的元素; 獲取生成的迭代器,從中構造一個反向迭代器,並將其分配給反向迭代器 it

使用 v.clear() 刪除所有元素不會釋放記憶體( 向量的 capacity() 保持不變)。要回收空間,請使用:

std::vector<int>().swap(v);
Version => C++ 11

shrink_to_fit() 釋放未使用的向量容量:

v.shrink_to_fit();

shrink_to_fit 並不能保證真正回收空間,但大多數現有的實施都可以。