容器和算法的改进 — C++20
C++ 20
对容器和算法有很多的改进
std::vector
和std::string
支持constexpr
- 所有容器支持
consistent container erasure
,contains
- 新的算法移动元素
std::shift_left
- 可以检查
std::string
的前缀和后缀
支持 constexpr
的容器和算法
C++ 20
的std::vector
和std::string
支持constexpr
- 超过100多种
algorithm
支持constexpr
这样, 你就可以实现在编译期查找字符串子串, 在编译期对数组进行排序
#include <ranges>
#include <vector>
#include <iostream>
#include <span>
#include <format>
#include <array>
#include <algorithm>consteval int maxEle()
{std::vector v{2, 4, 1, 6, 3, 8};std::sort(v.begin(), v.end());return v.back();
}consteval bool findSub(std::string s, std::string sub)
{return s.find(sub, 0) != std::string::npos;
}int main()
{constexpr int maxVal = maxEle();std::cout << maxVal << std::endl;std::cout << findSub("ianaworld", "world") << std::endl;
}
之所以能容器能在编译期能实现这些操作, 是因为使用了瞬态分配 Transient Allocation
Transient Allocation 瞬态分配
Transient Allocation
: 编译期申请的内存必须在编译期就释放, 不能将编译期申请的内存在运行时使用
#include <memory>constexpr auto correctRelease()
{auto* p = new int[2020];delete [] p;return 2020;
}constexpr auto forgottenRelease()
{auto* p = new int[2020];return 2020;
}constexpr auto falseRelease()
{auto* p = new int[2020];delete p;return 2020;
}int main()
{constexpr int res1 = correctRelease();constexpr int res2 = forgottenRelease();constexpr int res3 = falseRelease();
}
从容其中移除元素
在C++20 前是有一些复杂的
#include <algorithm>
#include <iostream>
#include <vector>int main()
{std::cout << '\n';std::vector myVec{-2, 3, -5, 10, 3, 0, -5};for (auto ele : myVec) std::cout << ele << " ";std::cout << "\n\n";std::remove_if(myVec.begin(), myVec.end(), [](int ele) { return ele < 0; });for (auto ele : myVec) std::cout << ele << " ";std::cout << "\n\n";
}
因为没有应用新的end
, 所以需要像下面这样做
#include <algorithm>
#include <iostream>
#include <vector>int main()
{std::cout << '\n';std::vector myVec{-2, 3, -5, 10, 3, 0, -5};for (auto ele : myVec) std::cout << ele << " ";std::cout << "\n\n";auto newEnd = std::remove_if(myVec.begin(), myVec.end(),[](int ele) { return ele < 0; });myVec.erase(newEnd, myVec.end());// myVec.erase(std::remove_if(myVec.begin(), myVec.end(),// [](int ele){ return ele < 0; }), myVec.end());for (auto ele : myVec) std::cout << ele << " ";std::cout << "\n\n";
}
C++ 20 之后
#include <algorithm>
#include <iostream>
#include <vector>int main()
{std::cout << '\n';std::vector myVec{-2, 3, -5, 10, 3, 0, -5};std::erase_if(myVec, [](int ele) { return ele >= 3; });for (int my_vec : myVec){std::cout << my_vec<<" ";}
}
其他容器也类似
contains
函数
可以方便的判断容器是否包含一个元素
C++ 20 之前
#include <set>
#include <iostream>int main()
{std::cout << '\n';std::set mySet{3, 2, 1};if (mySet.find(2) != mySet.end()){std::cout << "2 inside" << '\n';}std::multiset myMultiSet{3, 2, 1, 2};if (myMultiSet.count(2)){std::cout << "2 inside" << '\n';}std::cout << '\n';
}
比较长,并且对初学者不友好
C++ 20
#include <set>
#include <iostream>
#include <vector>int main()
{std::cout << std::boolalpha;std::cout << '\n';std::set mySet{3, 2, 1};std::cout << mySet.contains(2) << " ";}
这样就非常的简单了
std::shift_left/right
std::shift_left, std::shift_right - C++中文 - API参考文档 (apiref.com)
字符串前缀和后缀检查
starts_with
ends_with
Algorithms library - cppreference.com
文 - API参考文档 (apiref.com)](https://www.apiref.com/cpp-zh/cpp/algorithm/shift.html)
字符串前缀和后缀检查
starts_with
ends_with
Algorithms library - cppreference.com
std::shift_left, std::shift_right - C++中文 - API参考文档 (apiref.com)