前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >专栏 >跟Google学写代码--Chromium/base--stl_util源码学习及应用

跟Google学写代码--Chromium/base--stl_util源码学习及应用

作者头像
程序员的酒和故事
发布于 2018-03-12 09:17:06
发布于 2018-03-12 09:17:06
1.1K00
代码可运行
举报
运行总次数:0
代码可运行

Chromium是一个伟大的、庞大的开源工程,很多值得我们学习的地方。

今天与大家分享的就是Chromium下base中的stl_util,是对stl的补充,封装,更有利于我们的使用,完全可以移植到自己的C++工程项目中来。

1 释放STL内存 Clears internal memory of an STL object.

我们知道,vector的clear()方法式清除了vector中的内容,但是vector object所占的内存不会清除。

因此,std_util中有个这个方法:

代码语言:text
AI代码解释
复制
template<class T>void STLClearObject(T* obj) {
  T tmp;
  tmp.swap(*obj);  // Sometimes "T tmp" allocates objects with memory (arena implementation?).  // Hence using additional reserve(0) even if it doesn't always work.
  obj->reserve(0);
}

也就是使用swap,之前写过一篇博客: 《实战c++中的vector系列–正确释放vector的内存(clear(), swap(), shrink_to_fit())》 地址:http://blog.csdn.net/wangshubo1989/article/details/50359750

2 释放容器内的指针对象 这里隐藏了一个巨大的坑儿,就是迭代器的失效问题,之前也有博客里面介绍过:

《实战c++中的vector系列–可怕的迭代器失效(vector重新申请内存)》 地址:http://blog.csdn.net/wangshubo1989/article/details/50334297

《实战c++中的vector系列–可怕的迭代器失效之二(删除vector中元素)》 地址:http://blog.csdn.net/wangshubo1989/article/details/50334503

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
template <class ForwardIterator>void STLDeleteContainerPointers(ForwardIterator begin, ForwardIterator end) {  while (begin != end) {
    ForwardIterator temp = begin;
    ++begin;    delete *temp;
  }
}

3 正确删除容器内pairs对象

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
template <class ForwardIterator>void STLDeleteContainerPairPointers(ForwardIterator begin,
                                    ForwardIterator end) {  while (begin != end) {
    ForwardIterator temp = begin;
    ++begin;    delete temp->first;    delete temp->second;
  }
}

4 删除容器内pairs对象中的第一个元素

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
template <class ForwardIterator>void STLDeleteContainerPairFirstPointers(ForwardIterator begin,
                                         ForwardIterator end) {  while (begin != end) {
    ForwardIterator temp = begin;
    ++begin;    delete temp->first;
  }
}

5 删除容器内pairs对象中的第二个元素

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
template <class ForwardIterator>void STLDeleteContainerPairSecondPointers(ForwardIterator begin,
                                          ForwardIterator end) {  while (begin != end) {
    ForwardIterator temp = begin;
    ++begin;    delete temp->second;
  }
}

6 vector转为数组 一定要注意,vector可能为空的情况下。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
template<typename T>inline T* vector_as_array(std::vector<T>* v) {  return v->empty() ? NULL : &*v->begin();
}
代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
template<typename T>inline const T* vector_as_array(const std::vector<T>* v) {  return v->empty() ? NULL : &*v->begin();
}

7 string转为数组 还是是要注意string为空。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
inline char* string_as_array(std::string* str) {  // DO NOT USE const_cast<char*>(str->data())
  return str->empty() ? NULL : &*str->begin();
}

8 查找关联容器中是否有某个特定的key 没什么好说的,提高效率,函数的参数为const引用类型。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
template <typename Collection, typename Key>bool ContainsKey(const Collection& collection, const Key& key) {  return collection.find(key) != collection.end();
}

9 判断容器是否有序 这里用到了adjacent_find,在一个数组中寻找两个相邻的元素;

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
template <typename Container>bool STLIsSorted(const Container& cont) {  // Note: Use reverse iterator on container to ensure we only require
  // value_type to implement operator<.
  return std::adjacent_find(cont.rbegin(), cont.rend(),                            std::less<typename Container::value_type>())
      == cont.rend();
}

10 获得两个有序容器的不同 这里用到了DCHECK,是自己定义的宏:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
#define DCHECK(condition)                                               \
  LAZY_STREAM(LOG_STREAM(DCHECK), DCHECK_IS_ON ? !(condition) : false)  \
  << "Check failed: " #condition ". "
代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
template <typename ResultType, typename Arg1, typename Arg2>
ResultType STLSetDifference(const Arg1& a1, const Arg2& a2) {
  DCHECK(STLIsSorted(a1));
  DCHECK(STLIsSorted(a2));
  ResultType difference;  std::set_difference(a1.begin(), a1.end(),
                      a2.begin(), a2.end(),                      std::inserter(difference, difference.end()));  return difference;
}

11 合并两个有序的容器

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
template <typename ResultType, typename Arg1, typename Arg2>
ResultType STLSetUnion(const Arg1& a1, const Arg2& a2) {
  DCHECK(STLIsSorted(a1));
  DCHECK(STLIsSorted(a2));
  ResultType result;  std::set_union(a1.begin(), a1.end(),
                 a2.begin(), a2.end(),                 std::inserter(result, result.end()));  return result;
}

12 同时包含在两个容器中的元素 set_intersection:同时包含第一个和第二个集合中的元素

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
template <typename ResultType, typename Arg1, typename Arg2>
ResultType STLSetIntersection(const Arg1& a1, const Arg2& a2) {
  DCHECK(STLIsSorted(a1));
  DCHECK(STLIsSorted(a2));
  ResultType result;  std::set_intersection(a1.begin(), a1.end(),
                        a2.begin(), a2.end(),                        std::inserter(result, result.end()));  return result;
}

13 判断一个容器是否包含另一个容器的所有内容

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
template <typename Arg1, typename Arg2>bool STLIncludes(const Arg1& a1, const Arg2& a2) {
  DCHECK(STLIsSorted(a1));
  DCHECK(STLIsSorted(a2));  return std::includes(a1.begin(), a1.end(),
                       a2.begin(), a2.end());
}

应用: 对上面介绍的方法进行简单的使用,看看吧:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
#include<iostream>#include<vector>#include<algorithm>#include"stl_util.h"int main()
{  std::vector<int> numbers{1, 2, 3, 4, 6};  std::vector<int> numbers1{ 1, 2, 3 ,4};  std::cout << "Test STLIsSorted:{1, 2, 3, 4, 6}" << std::endl;  std::cout << std::boolalpha <<STLIsSorted(numbers) << std::endl << std::endl;  std::cout << "Test STLSetDifference {1, 2, 3, 4, 6} and { 1, 2, 3 ,4}:" << std::endl;  std::vector<int> difference_result;
  difference_result = STLSetDifference<std::vector<int>, std::vector<int>, std::vector<int>>(numbers, numbers1);  for(auto iter: difference_result)
  {    std::cout << iter << std::endl << std::endl;
  }  std::cout << "Test STLSetIntersection {1, 2, 3, 4, 6} and { 1, 2, 3 ,4}:" << std::endl;  std::vector<int> intersection_result;
  intersection_result = STLSetIntersection<std::vector<int>, std::vector<int>, std::vector<int>>(numbers, numbers1);  for (auto iter : intersection_result)
  {    std::cout << iter << " " ;
  }  std::cout << std::endl;  std::cout << "Test STLIncludes {1, 2, 3, 4, 6} and { 1, 2, 3 ,4}:" << std::endl;  std::cout << std::boolalpha << STLIncludes(numbers, numbers1) << std::endl << std::endl;  std::cout << "Test STLClearObject:" << std::endl;
  STLClearObject(&numbers);  std::cout << "vector size:" << numbers.size() << std::endl;  std::cout << "vector capacity:" << numbers.capacity() << std::endl << std::endl;

  system("pause");  return 0;
}

输出结果:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
Test STLIsSorted:{1, 2, 3, 4, 6}trueTest STLSetDifference {1, 2, 3, 4, 6} and { 1, 2, 3 ,4}:6Test STLSetIntersection {1, 2, 3, 4, 6} and { 1, 2, 3 ,4}:1 2 3 4Test STLIncludes {1, 2, 3, 4, 6} and { 1, 2, 3 ,4}:trueTest STLClearObject:vector size:0vector capacity:0
本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2017-01-16,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 人生有味是多巴胺 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
暂无评论
推荐阅读
编辑精选文章
换一批
C++学习之路—— STL标准模板库概述
1、map容器和vector容器的区别? map 是关联容器的一种,map 的每个元素都分为关键字和值两部分,容器中的元素是按关键字排序的,并且不允许有多个元素的关键字相同。 vector 是顺序容器,元素在其中按顺序存储,链表容器中内存不一定连续,但是按下标顺序存储的,每个元素都有唯一对应的位置编号 2、map容器和set容器的区别? set 是关联容器的一种,是排序好的集合(元素已经进行了排序)。且set容器中不能有重复的元素,set容器中元素的值不能直接修改。而Map不能直接修改 map 容器中的关键字。 map是带键值的容器,值是一个pair。 set是存储值的容器。 3、map容器和list容器的区别? list 是顺序容器的一种。map是带键值的容器,值是一个pair。 list本身是一个双向链表。 4、编写一个程序,来统计从键盘上输入单词的个数,如果碰到大写字符则不统计。
全栈程序员站长
2022/09/23
6230
C++学习之路—— STL标准模板库概述
9.1 C++ STL 排序、算数与集合
C++ STL(Standard Template Library)是C++标准库中的一个重要组成部分,提供了丰富的模板函数和容器,用于处理各种数据结构和算法。在STL中,排序、算数和集合算法是常用的功能,可以帮助我们对数据进行排序、统计、查找以及集合操作等。
王 瑞
2023/08/17
2470
跟Google学写代码--Chromium工程中用到的C++11特性
Ttile 跟Google学写代码--Chromium工程中用到的C++11特性 Chromium是一个伟大的、庞大的开源工程,很多值得我们学习的地方。 《跟Google学写代码–Chromium/base–stl_util源码学习及应用》 《跟Google学写代码–Chromium/base–windows_version源码学习及应用》 《跟Google学写代码–Chromium/base–cpu源码学习及应用》 今天就与大家一起分享一下Chromium中所用到的C++11特性,有的是之前博客没介绍过
程序员的酒和故事
2018/03/12
1.4K0
STL源码剖析_迭代器
按照《STL源码剖析》中STL知识的编排顺序,学习完空间配置器之后,就是迭代器和traits编程技法了,学习完这三个概念,才算做好了继续学习stl的准备。
yifei_
2022/11/14
3050
三十分钟掌握STL
这是本小人书。原名是《using stl》,不知道是谁写的。不过我倒觉得很有趣,所以化了两个晚上把它翻译出来。我没有对翻译出来的内容校验过。如果你没法在三十分钟内觉得有所收获,那么赶紧扔了它。文中我省略了很多东西。心疼那,浪费我两个晚上。 译者:kary contact:karymay@163.net STL概述 STL的一个重要特点是数据结构和算法的分离。尽管这是个简单的概念,但这种分离确实使得STL变得非常通用。例如,由于STL的sort()函数是完全通用的,你可以用它来操作几乎任何数据集合,包括链表,
猿人谷
2018/01/17
2.2K0
C++(STL):27 ---关联式容器set源码剖析
一、set set语法使用参阅: set的特性 set所有元素都会根据元素的键值自动被排序 set中的键值就是实值,实值就是键值 默认情况下set不允许两个元素重复 set的迭代器 不能根据set的迭代器改变set元素的值。因为其键值就是实值,实值就是键值,如果改变set元素值,会严重破坏set组织 在后面的源码中会看到,set的迭代器set<T>::iterator被定义为底层RB-tree的const_iterator。因此set的迭代器是一种constant iterators set拥有与lis
用户3479834
2021/02/03
7690
7.1 C++ STL 非变易查找算法
C++ STL 中的非变易算法(Non-modifying Algorithms)是指那些不会修改容器内容的算法,是C++提供的一组模板函数,该系列函数不会修改原序列中的数据,而是对数据进行处理、查找、计算等操作,并通过迭代器实现了对序列元素的遍历与访问。由于迭代器与算法是解耦的,因此非变易算法可以广泛地应用于各种容器上,提供了极高的通用性和灵活性。
王 瑞
2023/08/16
3670
STL set
STL 对这个序列可以进行查找,插入删除序列中的任意一个元素,而完成这些操作的时间同这个序列中元素个数的对数成比例关系,并且当游标指向一个已删除的元素时,删除操作无效。而一个经过更正的和更加实际的定义应该是:一个集合(set)是一个容器,它其中所包含的元素的值是唯一的。这在收集一个数据的具体值的时候是有用的。集合中的元素按一定的顺序排列,并被作为集合中的实例。一个集合通过一个链表来组织,在插入操作和删除操作上比向量(vector)快,但查找或添加末尾的元素时会有些慢。具体实现采用了红黑树的平衡二叉树的数据结构。
十四君
2019/11/27
6700
STL小结
STL就是Standard Template Library,标准模板库。这可能是一个历史上最令人兴奋的工具的最无聊的术语。从根本上说,STL是一些“容器”的集合,这些“容器”有list, vector,set,map等,STL也是算法和其它一些组件的集合。这里的“容器”和算法的集合指的是世界上很多聪明人很多年的杰作。是C++标准库的一个重要组成部分,它由Stepanov and Lee等人最先开发,它是与C++几乎同时开始开发的;一开始STL选择了Ada作为实现语言,但Ada有点不争气,最后他们选择了C++,C++中已经有了模板。STL又被添加进了C++库。1996年,惠普公司又免费公开了STL,为STL的推广做了很大的贡献。STL提供了类型安全、高效而易用特性的STL无疑是最值得C++程序员骄傲的部分。每一个C++程序员都应该好好学习STL。大体上包括container(容器)、algorithm(算法)和iterator(迭代器),容器和算法通过迭代器可以进行无缝连接。
Twcat_tree
2022/11/30
9530
STL小结
10.1 C++ STL 模板适配与迭代器
STL(Standard Template Library)标准模板库提供了模板适配器和迭代器等重要概念,为开发者提供了高效、灵活和方便的编程工具。模板适配器是指一组模板类或函数,它们提供一种适配机制,使得现有的模板能够适应新的需求。而迭代器则是STL中的令一种重要的概念,它是一个抽象化的数据访问机制,通过迭代器可以遍历STL容器中的元素。适配器与迭代器两者的紧密配合,使得开发者能够高效地处理容器中的元素,提高了代码的复用性和可维护性。
王 瑞
2023/08/17
2540
8.1 C++ STL 变易拷贝算法
C++ STL中的变易算法(Modifying Algorithms)是指那些能够修改容器内容的算法,主要用于修改容器中的数据,例如插入、删除、替换等操作。这些算法同样定义在头文件 <algorithm> 中,它们允许在容器之间进行元素的复制、拷贝、移动等操作,从而可以方便地对容器进行修改和重组。
王 瑞
2023/08/16
3240
万字长文【C++】函数式编程【上】
https://www.manning.com/books/functional-programming-in-c-plus-plus
用户9831583
2022/06/16
2.7K0
万字长文【C++】函数式编程【上】
从零开始学C++之STL(九):函数适配器bind2nd 、mem_fun_ref 源码分析、函数适配器应用举例
根据给定的文章内容,撰写摘要总结。
s1mba
2017/12/28
1K0
没想到!STL中sort有如此多亲戚邻居
需要 3 个随机访问迭代器 first、second 和 last,[first,second) 会包含降序序列 [first,last) 中最小的 second-first 个元素。
用户9831583
2022/06/16
2330
没想到!STL中sort有如此多亲戚邻居
C++13-STL模板
在线练习: http://noi.openjudge.cn/ https://www.luogu.com.cn/
IT从业者张某某
2023/10/16
3390
C++13-STL模板
现代C++实战篇(一)—泛型实现容器插入元素的自动排序
如果想要在容器中保存有序的字符串,往往需要我们自己手动排序。今天就实现一种可以在插入数据时就自动进行排序的方法。下面先来看下现在对vector元素排序的实现方法:
CPP开发前沿
2023/08/28
7510
现代C++实战篇(一)—泛型实现容器插入元素的自动排序
对vector等STL标准容器进行排序操作
STL几乎封装了所有的数据结构中的算法,从链表到队列,从向量到堆栈,对hash到二叉树,从搜索到排序,从增加到删除......可以说,如果你理解了STL,你会发现你已不用拘泥于算法本身,从而站在巨人的肩膀上去考虑更高级的应用。
bear_fish
2018/09/20
2.6K0
C++之STL标准模板库——从入门到精通
通俗说:STL是Standard Template Library(标准模板库),是高效的C++程序库,其采用泛型编程思想对常见数据结构(顺序表,链表,栈和队列,堆,二叉树,哈希)和算法(查找、排序、集合、数值运算…)等进行封装,里面处处体现着泛型编程程序设计思想以及设计模式,已被集成到C++标准程序库中。 具体说:STL中包含了容器、适配器、算法、迭代器、仿函数以及空间配置器。 STL设计理念:追求代码高复用性以及运行速度的高效率,在实现时使用了许多技术。
海盗船长
2020/08/27
1.1K0
C++ STL空间配置源码分析以及实现二
版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/haluoluo211/article/details/80573204
bear_fish
2018/09/14
6780
C++ STL空间配置源码分析以及实现二
C++效率掌握之STL库:list底层剖析及迭代器万字详解
为了与库里的 list 进行区分,所有的类和函数都放在自定义的命名空间 bit 进行区分
DARLING Zero two
2025/02/25
1890
C++效率掌握之STL库:list底层剖析及迭代器万字详解
相关推荐
C++学习之路—— STL标准模板库概述
更多 >
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档
本文部分代码块支持一键运行,欢迎体验
本文部分代码块支持一键运行,欢迎体验