C++ C++;矢量深度擦除

C++ C++;矢量深度擦除,c++,vector,stl,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){ stat

如何深层擦除向量

考虑以下代码

#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;
}
我想要的是访问v[I]以使从2到4的任何I无效,并使编译器抛出错误


简单地说,如何深层擦除向量?

您触发了未定义的行为,因此您的结果不可信

如果需要检查边界,请使用
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";
}
向量v{1,2,3,4,5};
v、 擦除(开始(v)+2,结束(v));
试一试{
自动值=v.at(4);
}捕获(标准::超出范围&){

cout您正在触发未定义的行为,因此您的结果不可信

如果需要检查边界,请使用
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";
}
向量v{1,2,3,4,5};
v、 擦除(开始(v)+2,结束(v));
试一试{
自动值=v.at(4);
}捕获(标准::超出范围&){

我现在没有时间给出例子,但我认为唯一能干净利落地做到这一点的方法是创建一个要包装的自定义类或子类vector。然后您可以生成一个自定义的
[]
at
运算符会在某些索引上引发错误。您甚至可以使用删除方法将索引添加到此禁用索引列表中


现在,如果您需要在编译时出现错误,这就更难了。我认为使用
constepr
access操作符和一些
static\u assert
s可能会有一些问题,但我不确定是否可以立即解决。

我现在没有时间给出示例,但我唯一能想到的干净方法是创建一个custom类包装或子类向量。然后,您可以生成自定义的
[]
at
运算符,这些运算符会在某些索引上引发错误。您甚至可以使用删除方法将索引添加到此禁用索引列表中



现在,如果您需要编译时的错误,这就更难了。我认为使用
constexpr
access操作符和一些
static\u assert
s可能会有一些问题,但我不确定是否立即执行。

它是UB;您应该自己检查它。或者改用
std::vector::at
。向量将其元素存储在con根据定义,内存太大,所以您想要的是不可能的,您甚至希望它是一个编译时错误。您不能使用std::vector将其作为编译时错误。它是UB;您应该自己检查它。或者使用
std::vector::at
代替。矢量根据定义将其元素存储在连续内存中,因此您想要的是不可能的你甚至希望它是一个编译时错误。你不能用std::vector将其作为编译时错误。访问运算符[]和at方法有什么区别?@kalpa
at
执行绑定检查,如果超出范围,则抛出运行时异常使用
[]访问向量是一种不好的做法吗
?@kalpa绝对不会,而且进行边界检查不会产生额外的开销。但要么你自己检查边界(例如
i
)或者你在使用<代码>不要因为你的时间而浪费很多时间……如果你可能的话,你能不能给我一些C++和UB的源代码?而at方法?@kalpa
at
进行边界检查,如果超出范围,则抛出运行时异常使用
[]
?@kalpa绝对不是,而且进行边界检查不会产生额外的开销。但是,要么你自己检查边界(例如
i
)或者在中使用<代码>不要为了你的时间而大量地浪费UB..也可以参考我的C++和STB库的一些来源,如果可能的话,如果代码>操作符[] /代码>产生UB,不做范围检查,那么为什么允许?也在< /代码> <代码>添加性能开销,与<代码>操作符[]相比]
?如果是,有多重要?@kalpa您评论的第二句回答了第一句,[]存在时at慢,具体慢到什么程度取决于运行时间,但我猜运行时间是3-10倍。当我调用
erase
clean
方法时,另一件事是内存解除分配还是直到整个向量被销毁才解除分配?@kalpa未指定此时是否解除分配内存,这取决于您的编译器和stdlib。但是请记住,我认为擦除会移动剩余的所有元素以填充空白,因此不会导致空白。如果
运算符[]
生成UB并且不进行范围检查,那么为什么允许这样做?与
运算符[]相比,
at
是否也会增加性能开销
?如果是,有多重要?@kalpa您评论的第二句回答了第一句,[]存在时at慢,具体慢到什么程度取决于运行时间,但我猜运行时间是3-10倍。当我调用
erase
clean
方法时,另一件事是内存解除分配还是直到整个向量被销毁才解除分配?@kalpa未指定此时是否解除分配内存,这取决于你的编译器和stdlib。但是请记住,我认为擦除会移动所有剩余的元素来填充空白,所以不会导致空白。