C ++ STL向量深度擦除

时间:2016-11-18 15:58:08

标签: c++ vector stl

如何深度擦除矢量?

请考虑以下代码。

#include<algorithm>
#include<iostream>
#include<iterator>
#include<vector>

using namespace std;

int main(){
    vector<int> v {1,2,3,4,5};
    for_each(begin(v),end(v),[&v](int& n){
        static auto i = (int)0;
        if(n == 2){
            v.erase ( begin(v) +2, end(v));
        }
        cout << n << "  having index " << i++ << endl;
    });
    v.erase ( begin(v) +2, end(v));
    cout << v.size() << endl << v[4] << endl;
}

输出

1  having index 0
2  having index 1
3  having index 2
4  having index 3
5  having index 4
2
4

我想要的是访问v [i],因为2到4的任何i都无效,编译器会抛出错误。

简单来说,如何深度擦除矢量?

2 个答案:

答案 0 :(得分:1)

您正在触发未定义的行为,因此您的结果无法信任。

如果您需要检查边界,请使用std::vector::at

vector<int> v{ 1,2,3,4,5 };
v.erase(begin(v) + 2, end(v));
try {
  auto val = v.at(4);
} catch (std::out_of_range&) {
  cout << "out of range";
}

除非您编写自己的工具或解决方法,否则不能对std::vector进行此类编译时检查。更多信息和一些建议:https://stackoverflow.com/a/32660677/1938163

答案 1 :(得分:1)

我现在没有时间提供示例,但我能想到干净利落的唯一方法是创建自定义类来包装或子类化向量。然后,您可以生成自定义[]at运算符,这些运算符会在某些索引上引发错误。你甚至可以有一个删除方法,它可以为这个被禁止的列表添加一些。

现在如果在编译时需要错误,那就更难了。我认为使用constexpr访问运算符和一些static_assert可能会有一些事情,但我不确切地知道它是多么偏离。