std::variant
类模板 std::variant 表示一个范例
安全的 union。std::variant 的实例在任何给定时间都持有一个其替代范例的值(它也可以是无值的)
- std::variant<int, double> v{ 12 };
- std::get<int>(v); // == 12
- std::get<0>(v); // == 12
- v = 12.0;
- std::get<double>(v); // == 12.0
- std::get<1>(v); // == 12.0
std:
ptional
类模板 std:

ptional 管理一个可选的包罗值,即一个大概存在也大概不存在的值。optional 的常见用例是函数的返回值,该函数大概会失败
- std::optional<std::string> create(bool b) {
- if (b) {
- return "Godzilla";
- } else {
- return {};
- }
- }
- create(false).value_or("empty"); // == "empty"
- create(true).value(); // == "Godzilla"
- // 返回 optional 的工厂函数可以用作 while 和 if 的条件
- if (auto str = create(true)) {
- // ...
- }
std::any
一个范例
安全的
容器,用于
存储任何范例的单个值
- std::any x {5};
- x.has_value() // == true
- std::any_cast<int>(x) // == 5
- std::any_cast<int&>(x) = 10;
- std::any_cast<int>(x) // == 10
std::string_view
对字符串的非拥有引用。它实用于在字符串上提供抽象(比方用于分析)
- // 普通字符串。
- std::string_view cppstr {"foo"};
- // 宽字符串。
- std::wstring_view wcstr_v {L"baz"};
- // 字符数组。
- char array[3] = {'b', 'a', 'r'};
- std::string_view array_v(array, std::size(array));
- std::string str {" trim me"};
- std::string_view v {str};
- v.remove_prefix(std::min(v.find_first_not_of(" "), v.size()));
- str; // == " trim me"
- v; // == "trim me"
std::invoke
调用一个 Callable 对象及其参数。可调用 对象的示例包罗 std::function 或 lambda;可以像平常函数一样调用的对象
- template <typename Callable>
- class Proxy {
- Callable c_;
- public:
- Proxy(Callable c) : c_{ std::move(c) } {}
- template <typename... Args>
- decltype(auto) operator()(Args&&... args) {
- // ...
- return std::invoke(c_, std::forward<Args>(args)...);
- }
- };
- const auto add = [](int x, int y) { return x + y; };
- Proxy p{ add };
- p(1, 2); // == 3
std::apply
利用元组的参数调用一个 Callable 对象
- auto add = [](int x, int y) {
- return x + y;
- };
- std::apply(add, std::make_tuple(1, 2)); // == 3
std::filesystem
新的 std::filesystem 库提供了一种尺度的方式来利用文件、目次和文件体系中的路径。
以下是一个大文件被复制到暂时路径的示例,条件是存在充足的空间:
- const auto bigFilePath {"bigFileToCopy"};
- if (std::filesystem::exists(bigFilePath)) {
- const auto bigFileSize {std::filesystem::file_size(bigFilePath)};
- std::filesystem::path tmpPath {"/tmp"};
- if (std::filesystem::space(tmpPath).available > bigFileSize) {
- std::filesystem::create_directory(tmpPath.append("example"));
- std::filesystem::copy_file(bigFilePath, tmpPath.append("newFile"));
- }
- }
std::byte
新的 std::byte 范例提供了一种尺度的方式来表示数据为字节。利用 std::byte 而不是 char 或 unsigned char 的利益是它不是字符范例,也不是算术范例;唯一可用的运算符重载是按位运算
- std::byte a {0};
- std::byte b {0xFF};
- int i = std::to_integer<int>(b); // 0xFF
- std::byte c = a & b;
- int j = std::to_integer<int>(c); // 0
留意,std::byte 只是一个罗列范例,而罗列的直接列表初始化成为大概,这得益于罗列的直接列表初始化
映射和聚集的拼接
在没有昂贵的拷贝、移动或堆分配/释放开销的情况下,移动节点和合并
容器。
从一个映射移动元素到另一个映射:
- std::map<int, string> src {{1, "one"}, {2, "two"}, {3, "buckle my shoe"}};
- std::map<int, string> dst {{3, "three"}};
- dst.insert(src.extract(src.find(1))); // 从 `src` 到 `dst` 廉价地移除并插入 { 1, "one" }
- dst.insert(src.extract(2)); // 从 `src` 到 `dst` 廉价地移除并插入 { 2, "two" }
- // dst == { { 1, "one" }, { 2, "two" }, { 3, "three" } };
插入整个聚集:
- std::set<int> src {1, 3, 5};
- std::set<int> dst {2, 4, 5};
- dst.merge(src);
- // src == { 5 }
- // dst == { 1, 2, 3, 4, 5 }
插入超出
容器生命周期的元素:
- auto elementFactory() {
- std::set<...> s;
- s.emplace(...);
- return s.extract(s.begin());
- }
- s2.insert(elementFactory());
更改映射元素的键:
- std::map<int, string> m {{1, "one"}, {2, "two"}, {3, "three"}};
- auto e = m.extract(2);
- e.key() = 4;
- m.insert(std::move(e));
- // m == { { 1, "one" }, { 3, "three" }, { 4, "two" } }
并行算法
许多 STL 算法(如 copy、find 和 sort)开始支持 并行实验计谋:seq、par 和 par_unseq,分别表示"次序"、“并行"和"并行无序”。
- std::vector<int> longVector;
- // 使用并行执行策略查找元素
- auto result1 = std::find(std::execution::par, std::begin(longVector), std::end(longVector), 2);
- // 使用顺序执行策略排序元素
- auto result2 = std::sort(std::execution::seq, std::begin(longVector), std::end(longVector));
std::sample
从给定序列中随机抽样 n 个元素(不放回),每个元素被选中的概率相称。
- const std::string ALLOWED_CHARS = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";
- std::string guid;
- // 从 ALLOWED_CHARS 中随机抽样 5 个字符。
- std::sample(ALLOWED_CHARS.begin(), ALLOWED_CHARS.end(), std::back_inserter(guid),
- 5, std::mt19937{ std::random_device{}() });
- std::cout << guid; // 例如:G1fW2
std::clamp
将给定值限定在上下界之间。
- std::clamp(42, -1, 1); // == 1
- std::clamp(-42, -1, 1); // == -1
- std::clamp(0, -1, 1); // == 0
- // `std::clamp` 也接受自定义比较器:
- std::clamp(0, -1, 1, std::less<>{}); // == 0
std::reduce
对给定范围的元素举行折叠利用。它与 std::accumulate 概念上雷同,但 std::reduce 会并行实验折叠利用。由于折叠是并行实验的,假如指定了二元运算符,则要求它是联合的和交换的。给定的二元运算符也不应修改范围内的任何元素或使任何迭代器失效。
默认的二元运算是 std::plus,初始值为 0
- const std::array<int, 3> a{ 1, 2, 3 };
- std::reduce(std::cbegin(a), std::cend(a)); // == 6
- // 使用自定义二元运算符:
- std::reduce(std::cbegin(a), std::cend(a), 1, std::multiplies<>{}); // == 6
别的,还可以为归约器指定转换利用:
- std::transform_reduce(std::cbegin(a), std::cend(a), 0, std::plus<>{}, times_ten); // == 60
- const std::array<int, 3> b{ 1, 2, 3 };
- const auto product_times_ten = [](const auto a, const auto b) { return a * b * 10; };
- std::transform_reduce(std::cbegin(a), std::cend(a), std::cbegin(b), 0, std::plus<>{}, product_times_ten); // == 140
前缀和算法
支持前缀和(包罗包罗扫描和清除扫描)以及转换。
- const std::array<int, 3> a{ 1, 2, 3 };
- std::inclusive_scan(std::cbegin(a), std::cend(a),
- std::ostream_iterator<int>{ std::cout, " " }, std::plus<>{}); // 1 3 6
- std::exclusive_scan(std::cbegin(a), std::cend(a),
- std::ostream_iterator<int>{ std::cout, " " }, 0, std::plus<>{}); // 0 1 3
- const auto times_ten = [](const auto n) { return n * 10; };
- std::transform_inclusive_scan(std::cbegin(a), std::cend(a),
- std::ostream_iterator<int>{ std::cout, " " }, std::plus<>{}, times_ten); // 10 30 60
- std::transform_exclusive_scan(std::cbegin(a), std::cend(a),
- std::ostream_iterator<int>{ std::cout, " " }, 0, std::plus<>{}, times_ten); // 0 10 30
最大公约数和最小公倍数
最大公约数(GCD)和最小公倍数(LCM)
- const int p = 9;
- const int q = 3;
- std::gcd(p, q); // == 3
- std::lcm(p, q); // == 9
std::not_fn
实用函数,返回给定函数效果的否定
- const std::ostream_iterator<int> ostream_it{ std::cout, " " };
- const auto is_even = [](const auto n) { return n % 2 == 0; };
- std::vector<int> v{ 0, 1, 2, 3, 4 };
- // 打印所有偶数。
- std::copy_if(std::cbegin(v), std::cend(v), ostream_it, is_even); // 0 2 4
- // 打印所有奇数(非偶数)。
- std::copy_if(std::cbegin(v), std::cend(v), ostream_it, std::not_fn(is_even)); // 1 3
字符串与数字的相互转换
将整数和浮点数转换为字符串,反之亦然。这些转换是不抛出非常的,不会举行分配,而且比 C 尺度库中的等效函数更
安全。
用户负责为 std::to_chars 分配充足的
存储空间,否则函数将通过在其返回值中设置错误
代码对象来失败。
这些函数允许您可选地转达基数(默认为 10 进制)或浮点输入的格式说明符。
std::to_chars 返回一个(非 const)字符指针,指向函数在给定缓冲区内写入的字符串的末端,以及一个错误
代码对象。
std::from_chars 返回一个 const 字符指针,成功时等于转达给函数的结束指针,以及一个错误
代码对象。
这两个函数返回的错误代码对象在成功时都等于默认初始化的错误代码对象。
将数字 123 转换为 std::string:
- const int n = 123;
- // 可以使用任何容器,字符串,数组等。
- std::string str;
- str.resize(3); // 为 `n` 的每个数字分配足够的存储空间
- const auto [ ptr, ec ] = std::to_chars(str.data(), str.data() + str.size(), n);
- if (ec == std::errc{}) { std::cout << str << std::endl; } // 123
- else { /* 处理失败 */ }
从值为 “123” 的 std::string 转换为整数:
- const std::string str{ "123" };
- int n;
- const auto [ ptr, ec ] = std::from_chars(str.data(), str.data() + str.size(), n);
- if (ec == std::errc{}) { std::cout << n << std::endl; } // 123
- else { /* 处理失败 */ }
chrono 连续时间和时间点的舍入函数
为 std::chrono::duration 和 std::chrono::time_point 提供 abs、round、ceil 和 floor 辅助函数
- using seconds = std::chrono::seconds;
- std::chrono::milliseconds d{ 5500 };
- std::chrono::abs(d); // == 5s
- std::chrono::round<seconds>(d); // == 6s
- std::chrono::ceil<seconds>(d); // == 6s
- std::chrono::floor<seconds>(d); // == 5s
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。