在开源项目或项目中使用git建立fork仓库

作者: 良知犹存

前言:

vector们经常使用,对vector里面的基本函数构造函数、增加函数、删除函数、遍历函数们也会用到。其中在使用遍历之后erase删除元素过程中,会出现一种删除最后一个元素破坏了迭代器的情况。

如下所示 删除到最后一个元素的时候就会报错

vector<int> data(10);
auto temp_begin = data.begin(), temp_end= data.end();
for(;temp_begin!=temp_end;){
    data.erase(temp_begin);
}

产生这个问题的原因是:当们调用erase方法删除元素的时候,erase方法会返回下一个元素的迭代器。当删除到最后一个元素的时候,这个时候返回的是最后一个元素之后的容器,而不是最后一个元素。

作者:良知犹存

转载授权以及围观:欢迎关注微信公众号:羽林君

或者添加作者个人微信:become_me


原因分析: {原因分析:}

vector:

Because vectors keep an array format, erasing on positions other than the vector end also moves all the elements after the segment erased to their new positions, which may not be a method as efficient as erasing in other kinds of sequence containers (deque, list). This invalidates all iterator and references to position (or first) and its subsequent elements.

假设你的 vector 中有多个对象,最后一个被标记为销毁。当您调用erase时,它将返回一个新的有效迭代器,该迭代器指向已删除元素之后的元素。被删除的元素之后没有元素,因此返回的迭代器为data.end()。

然后,们继续循环的顶部并取消引用此迭代器,这是无效的。如果要让迭代器指向有效元素,则需要在擦除后减少其迭代器。
vec.end() 给你元素的迭代器以下容器的最后一个元素。看这里:

list和vector区别(list 这样删除就没事) {list和vector区别list-这样删除就没事}

List:

This effectively reduces the list size by the number of elements removed, calling each element's destructor before.

lists are sequence containers specifically designed to be efficient inserting and removing elements in any position, even in the middle of the sequence. Compared to the other base sequence containers (vector and deque), lists are the most efficient container erasing at some position other than the beginning or the end of the sequence, and, unlike in these, all of the previously obtained iterators and references remain valid after the erasing operation and refer to the same elements they were referring before (except, naturally, for those referring to erased elements).

列表是序列容器,专门设计用于在任何位置高效插入和删除元素,甚至在序列的中间。list erase不会改变原来的iterator,所以不会出现像vector删除最后一个iterator后程序错误。

修改建议 {修改建议}

下面修改的建议都是让vector的end迭代器可以一直更新,重新判断当前位置。

vector<int> data(10);
auto iter = data.begin();
while(iter != data.end())
{
  data.erase(iter);
}

for (iter = data.begin(); it != data.end();)
{
    data.erase(iter);
}

将删除最后一个元素

data.erase(data.end() - 1); 


 data.erase(data.begin() + data.size() - 1); 

应该提到的是,如果向量为空,则该操作将崩溃,因此出于安全考虑,们可以再添加一个vector是否为空的判断

if (!data.empty())
  data.erase(vec.end() - 1);

另外们也发现 vector 的 erase 需要整个vector 移动,这个代价十分高,所以尽量少用。若排序顺序不是很重要的话,可以和最后的那个item swap,然后删掉最后那个,这样可以显著的提高效率。

结语

这就是分享的项目中一些vector使用,如果大家有更好的想法和需求,也欢迎大家加好友交流分享哈。


作者:良知犹存,白天努力工作,晚上原创公号号主。公众号内容除了技术还有些人生感悟,一个认真输出内容的职场老司机,也是一个技术之外丰富生活的人,摄影、音乐 and 篮球。关注,与一起同行。

                                                ‧‧‧‧‧‧‧‧‧‧‧‧‧‧‧‧  END  ‧‧‧‧‧‧‧‧‧‧‧‧‧‧‧‧

推荐阅读

【1】C++的智能指针你了解吗?

【2】嵌入式底层开发的软件框架简述

【3】CPU中的程序是怎么运行起来的 必读

【4】cartographer环境建立以及建图测试

【5】设计模式之简单工厂模式、工厂模式、抽象工厂模式的对比

本公众号全部原创干货已整理成一个目录,回复[ 资源 ]即可获得。

原文作者:良知犹存

原文链接:https://www.cnblogs.com/conscience-remain/p/15389449.html

更多推荐

更多
  • Git秘籍-十二、使用 Github 在这一章中,我将讨论使用 Github 来托管存储库。目前这是一个流行的开源项目托管平台。我们首先创建一个 Github 帐户并配置 SSH 密钥。完成后,您将学会如何:从公共 Github 库克隆克隆并推送至
    Apache CN

  • Git秘籍-十三、更多秘籍 在这最后一章,我将讨论一些尚未涉及的细节,这些细节迟早会成为你不可或缺的。您将了解到:如何使用命令`$ git diff`比较不同版本的文件?如何克服关于行尾的问题?配置忽略文件的三种不同方法使
    Apache CN

  • Git秘籍-十一、托管 Git 存储库 一旦你和你的同事们学会了如何提交、使用分支和远程操作,你就会想把 git 作为一个团队来使用。在这一章中,我将展示如何建立一个虚拟主机来与他人共享 git 库。 Git 可以使用 ssh、http、https 和 git 网络协议。要
    Apache CN

  • Git秘籍-十、远程存储库和同步 所有 VCS 系统背后的内在原因是使一组开发人员之间的协作尽可能无缝。最后,我们已经到了可以讨论如何使用 git 进行小组工作的时候了。我们将从最简单的设置开始,所有的存储库都可以通过本地存储获得。首先你必须学会如何使用遥控器。我
    Apache CN

  • Git秘籍-九、解决冲突 到目前为止,我们主要关注修订图的结构。我们通常使用别名`$ git simple-commit`提交;因此,我们生成的文件非常简单。事实上,到目前为止我们创建的几乎每个文件都只包含一个单词。一旦创建,这些文件很少被修改。此外,秘籍是以
    Apache CN

  • Git秘籍-四、管理文件 在本章中,我们将练习和分析在工作目录中使用的文件系统命令。我们将创建、修改、删除和重命名文件,并检查这些操作如何影响存储库。正如您已经知道的,git 不会自动注册工作目录中的更改。要创建新版本,您必须发出特殊命令: ``` $ g
    Apache CN

  • Git秘籍-五、分支 每当我被问及从旧版本的控制系统(VCS,如 CVS 或 Subversion)转换到 git 的好处时;我用这个简短的陈述来回答:git 分支模型。一旦你学会使用它,你会问自己,没有它我究竟是怎么工作的?事实上,git 处理分支的方式
    Apache CN

  • Git秘籍-六、合并分支 创建和切换分支的命令允许您将项目分成独立的开发线。例如,您可以创建分支来启动应用中的新功能或实现修复。迟早你会完成一个特性或修复,然后很可能,你会想把你的努力融入到开发的主线中。连接不同分支的过程可以使用两种不同的技术来完成。第一个是
    Apache CN

  • Git秘籍-七、分支变基 你可以用`$ git merge`和`$ git rebase`命令连接两个不同的开发历史。在这一章中,我们将讨论重定基。合并在前一章已经讨论过了。一般来说,重置基础是一种将分歧分支转换成线性历史的方法。您可以将它看作是一个自动的
    Apache CN

  • Git秘籍-八、修改历史记录 本章介绍修改修订图结构的各种命令。有时你需要将三个不同的版本合并成一个版本。在其他时候,您可能需要相反的操作:将一个单独的提交分成许多单独的提交。无论是哪种情况,请记住 git 版本是永久的。他们永远不会改变。一旦创建了修订,就无法对
    Apache CN

  • 近期文章

    更多
    文章目录

      推荐作者

      更多