在实际编程中 , 还是不太建议使用全局静态对象,建议的写法:
要声明全局的常量字符串,可以使用 const 关键字和 extern 关键字的组合:
// constants.hextern const char* GLOBAL_STRING;// constants.cpp#include "constants.h"const char* GLOBAL_STRING = "Hello, world!";constexpr char* kVal="hahhahah";使用 constexpr 关键字来声明全局的常量字符串:// constants.hconstexpr const char* GLOBAL_STRING = "Hello, world!";迭代器删除在处理缓存时 , 容器元素的增删查改是很常见的 , 通过迭代器去删除容器(vector/map/set/unordered_map/list)元素也是常有的,但这其中使用不当也会存在很多坑 。
std::vector<int> numbers = { 88, 101, 56, 203, 72, 135 };auto it = std::find_if(numbers.begin(), numbers.end(), [](int num) { return num > 100 && num % 2 != 0;});vec.erase(it);上面代码,查找std::vector中大于 100 并且为奇数的整数并将其删除 。std::find_if 将从容器的开头开始查找,直到找到满足条件的元素或者遍历完整个容器,并返回迭代器it , 然后去删除该元素 。但是这里没有判断it为空的情况,直接就erase了,如果erase一个空的迭代器会引发crash 。很多新手程序员会犯这样的错误,随时判空是个不错的习惯 。
删除元素不得不讲下std::remove 和 std::remove_if,用于从容器中移除指定的元素,函数会将符合条件的元素移动到容器的末尾,并返回指向新的末尾位置之后的迭代器,最后使用容器的erase来擦除从新的末尾位置开始的元素 。
std::vector<std::string> vecs = { "A", "", "B", "", "C", "hhhhh", "D" };vecs.erase(std::remove(vecs.begin(), vecs.end(), ""), vecs.end());// 移除所有偶数元素vec.erase(std::remove_if(vec.begin(), vec.end(), [](int x) { return x % 2 == 0; }), vec.end());这里的erase不用判空,其内部实现已经有判空处理 。
_CONSTEXPR20 iterator erase(const_iterator _First, const_iterator _Last) noexcept( is_nothrow_move_assignable_v<value_type>) /* strengthened */ { const pointer _Firstptr = _First._Ptr; const pointer _Lastptr = _Last._Ptr; auto& _My_data = _Mypair._Myval2; pointer& _Mylast = _My_data._Mylast; // .... if (_Firstptr != _Lastptr) { // something to do, invalidate iterators _Orphan_range(_Firstptr, _Mylast); const pointer _Newlast = _Move_unchecked(_Lastptr, _Mylast, _Firstptr); _Destroy_range(_Newlast, _Mylast, _Getal()); _Mylast = _Newlast; } return iterator(_Firstptr, _STD addressof(_My_data));}此外,STL容器的删除也要小心迭代器失效,先来看个vector、list、map删除的例子:
// vector、list、map遍历并删除偶数元素std::vector<int> elements = { 1, 2, 3, 4, 5 };for (auto it = elements.begin(); it != elements.end();) { if (*it % 2 == 0) { elements.erase(it++); } else { it++; }}// Errorstd::list<int> cont{ 88, 101, 56, 203, 72, 135 };for (auto it = cont.begin(); it != cont.end(); ) { if (*it % 2 == 0) { cont.erase(it++); } else { it++; }}// Ok std::map<int, std::string> myMap = { {1, "one"}, {2, "two"}, {3, "three"}, {4, "four"}, {5, "five"} };// 遍历并删除键值对 , 删除键为偶数的元素for (auto it = myMap.begin(); it != myMap.end(); ) { if (it->first % 2 == 0) { myMap.erase(it++); } else { it++; }}// Ok
推荐阅读
- 沙滩裤最常见的面料有哪些 沙滩裤首选什么面料
- 7种常见水果,秋天吃正是好时候,健康促消化对吗
- 常见鸟类的本领和特征 常见鸟类的本领
- 八个 C++ 开源项目,帮助初学者进阶成长
- 买车分期与全款:内行揭秘,新手购车避坑指南
- 常见泵原理图 泵的结构与原理图
- U盘使用过程中常见问题及其解决方案
- SSL协议是什么?关于SSL和TLS的常见问题解答
- 衣服的常见面料,十大常见服装面料优缺点分析
- C++多线程编程:解锁性能与并发的奥秘
