最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

C++20新特性之Range庫

 更新時間:2026年06月04日 09:05:24   作者:樓田莉子  
本文主要介紹了C++20新特性之Range庫,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧

之前我們已經(jīng)學(xué)習(xí)過C++20的概念與約束。今天我們就來學(xué)習(xí)繼承了概念與約束的標(biāo)準(zhǔn)庫新的功能庫Range庫

官方文檔:Standard library header <ranges> (C++20) - cppreference.com

Range庫介紹

前言

Ranges 是對 STL 算法與迭代器體系的一次根本性重構(gòu)。 傳統(tǒng) STL 算法用一對迭代器 [begin, end) 表示操作范圍,而 Ranges 將這個"范圍"抽象為一等公民——一個可以直接傳遞的對象。

核心變化:

// C++17 傳統(tǒng)寫法:必須傳兩個迭代器
std::sort(vec.begin(), vec.end());

// C++20 Ranges 寫法:傳一個 range 對象即可
std::ranges::sort(vec);

這個看似微小的語法變化背后,是整個泛型編程范式的升級。

包含內(nèi)容

整個庫基于 <ranges> 頭文件,分為四大層次:

1. 核心概念(Concepts)—— 類型系統(tǒng)的基石

Concept含義
std::ranges::range任何有 begin() 和 end() 的類型
std::ranges::sized_range可以在常數(shù)時間獲取大小的 range
std::ranges::view輕量級、O(1) 拷貝/移動的 range
std::ranges::input_range至少支持輸入迭代器的 range
std::ranges::forward_range支持前向迭代器
std::ranges::bidirectional_range支持雙向迭代器
std::ranges::random_access_range支持隨機(jī)訪問迭代器
std::ranges::contiguous_range內(nèi)存連續(xù)布局(如 vector, array, span)
std::ranges::common_rangebegin() 和 end() 返回相同類型的 range

2. 算法(Algorithms)——std::ranges::命名空間

所有傳統(tǒng) STL 算法的 Range 版本,約束在 std::ranges 命名空間下。與傳統(tǒng)算法有兩個關(guān)鍵區(qū)別:

  • 第一個參數(shù)是 range 對象,而非迭代器對
  • 返回類型更豐富:不再只返回一個迭代器,而是返回包含更多信息的結(jié)構(gòu)化結(jié)果
// 傳統(tǒng) STL:返回迭代器,要找插入位置還得再算
auto it = std::find(vec.begin(), vec.end(), 42);

// C++20 Ranges:接受 range,返回迭代器
auto it = std::ranges::find(vec, 42);

3. Range 適配器(Range Adaptors)—— 惰性管道

這是 Ranges 庫最具革命性的部分。適配器是惰性求值的視圖轉(zhuǎn)換,通過 | 管道運算符串聯(lián),構(gòu)成聲明式的數(shù)據(jù)處理流水線:

適配器作用
std::views::filter(pred)按謂詞過濾元素
std::views::transform(fn)對每個元素應(yīng)用函數(shù)
std::views::take(n)取前 n 個元素
std::views::drop(n)跳過前 n 個元素
std::views::take_while(pred)取滿足條件的連續(xù)前綴
std::views::drop_while(pred)丟棄滿足條件的連續(xù)前綴
std::views::reverse反轉(zhuǎn)范圍
std::views::join展平嵌套 range
std::views::split(delim)按分隔符切分
std::views::common轉(zhuǎn)換為 common_range
std::views::keys / values提取 pair/tuple 的 key 或 value
std::views::iota生成遞增序列
std::views::all將 range 包裝為 view

4. 工廠(Factories / Range Factories)

不需要輸入 range,直接生成 range 的工具:

  • std::views::iota(start, end) — 生成 [start, end) 整數(shù)序列
  • std::views::empty<T> — 空 range
  • std::views::single(x) — 只包含單一元素的 range
  • std::views::istream<T>(stream) — 從輸入流讀取

優(yōu)勢

消滅迭代器對——代碼量減半

// C++17:寫兩遍容器名
std::sort(v.begin(), v.end());
auto it = std::find_if(v.begin(), v.end(), pred);

// C++20:容器名只出現(xiàn)一次
std::ranges::sort(v);
auto it = std::ranges::find_if(v, pred);

這不是語法糖——它消除了迭代器不匹配的可能性,從類型系統(tǒng)層面杜絕了 sort(v1.begin(), v2.end()) 這類經(jīng)典 bug。

管道組合——從命令式到聲明式

這是最重要的心智模型轉(zhuǎn)變。傳統(tǒng)寫法是命令式的:你需要一步步告訴 CPU 要做什么。管道寫法是聲明式的:你描述數(shù)據(jù)應(yīng)該經(jīng)過怎樣的變換。

// C++17 命令式:需要中間容器,多次遍歷
std::vector<int> even;
std::copy_if(v.begin(), v.end(), std::back_inserter(even),
             [](int x) { return x % 2 == 0; });
std::vector<int> squared;
std::transform(even.begin(), even.end(), std::back_inserter(squared),
               [](int x) { return x * x; });
auto it = std::find_if(squared.begin(), squared.end(),
                       [](int x) { return x > 100; });

// C++20 聲明式:一次遍歷,零拷貝,惰性求值
auto result = v
    | std::views::filter([](int x) { return x % 2 == 0; })
    | std::views::transform([](int x) { return x * x; })
    | std::views::drop_while([](int x) { return x <= 100; });

for (auto x : result) { /* 只在遍歷時才真正計算 */ }

惰性求值——零開銷抽象

管道中的每個適配器在定義時不執(zhí)行任何計算。計算被推遲到消費時才發(fā)生,且所有變換融合成單次遍歷。沒有中間分配,沒有額外拷貝。

更豐富的返回值

傳統(tǒng) std::find 只返回一個迭代器,還需要重新計算到開頭的距離等操作。Range 算法返回結(jié)構(gòu)化的結(jié)果對象:

// C++17
auto it = std::find(v.begin(), v.end(), 42);
auto pos = std::distance(v.begin(), it); // 又遍歷一次

// C++20:直接通過結(jié)構(gòu)化綁定獲取所需信息
struct find_result { iterator found; bool success; }; // 偽代碼示例
// 實際例子——ranges::sort 返回 borrowed_iterator_t<R>

投影(Projection)——無需 Lambda 包裝器

每個 Range 算法都支持一個 Projection 參數(shù),可以在比較/操作之前對元素做變換,而無需手動寫 lambda:

// C++17:lambda 包裝比較
std::sort(v.begin(), v.end(),
          [](const Person& a, const Person& b) { return a.age < b.age; });

// C++20:投影 + 默認(rèn)比較
std::ranges::sort(v, std::less{}, &Person::age);
//                    ^^^^^^^^^  ^^^^^^^^^^^^
//                    比較函數(shù)      投影(要對什么排序)

Concepts 約束——編譯期安全帶

Range 算法通過 Concept 對其輸入做了嚴(yán)格約束。如果一個類型不滿足 input_range,調(diào)用 ranges::find 在編譯期就會給出清晰的錯誤信息,而不是在實例化后拋出幾十行的模板錯誤。

int x = 42;
// std::ranges::sort(x);  // 編譯錯誤,清晰提示 int 不是 range

對內(nèi)置數(shù)組和std::span的原生支持

int arr[] = {3, 1, 4, 1, 5};
std::ranges::sort(arr);  // 直接對 C 數(shù)組排序,不需要 std::begin/std::end

Range視圖

視圖的核心特點與優(yōu)勢

視圖 (View) 是 Ranges 庫的核心抽象,具有以下關(guān)鍵特征:

  1. O(1) 拷貝/移動 — 視圖不擁有數(shù)據(jù),只持有底層 range 的引用或輕量級狀態(tài)
  2. 惰性求值 — 定義管道時不執(zhí)行任何計算,消費時才按需計算
  3. 融合遍歷 — 多個視圖通過 | 串聯(lián)后,編譯器將其融合為等效的單次手寫循環(huán)
  4. 不修改原數(shù)據(jù) — 視圖是"數(shù)據(jù)的觀察窗口",變換操作生成新視圖而不修改底層容器
  5. 編譯期類型安全 — 基于 Concepts 約束,視圖間的非法連接會在編譯期被攔截

適配器視圖

需要輸入 range,對數(shù)據(jù)做變換

適配器功能典型場景
filter(pred)保留滿足謂詞的元素篩選偶數(shù)、有效記錄
transform(fn)對每個元素應(yīng)用映射函數(shù)類型轉(zhuǎn)換、提取字段
take(n)取前 n 個元素后停止分頁、TOP-N 查詢
drop(n)跳過前 n 個元素跳過表頭、去除前導(dǎo)
take_while(pred)取滿足條件的連續(xù)前綴讀取到終止標(biāo)記
drop_while(pred)丟棄滿足條件的連續(xù)前綴去除前導(dǎo)空白
reverse反轉(zhuǎn) range(需 bidirectional)逆序遍歷
split(delim)按分隔符切割(range of ranges)字符串分詞
join展平嵌套 range二維轉(zhuǎn)一維
keys提取 pair/tuple 的第一個元素遍歷 map 的 key
values提取 pair/tuple 的第二個元素遍歷 map 的 value
all將 range 包裝為 view顯式開啟管道
common統(tǒng)一 begin() 和 end() 返回類型適配遺留接口

代碼示例:

#include <algorithm>
#include <iostream>
#include <ranges>
#include <vector>
#include <string>
#include <map>
#include <list>
#include <sstream>

namespace r = std::ranges;
namespace v = std::views;

template<typename R>
void print_range(std::string_view name, R&& r) {
    std::cout << name << ": ";
    for (auto&& e : r) std::cout << e << ' ';
    std::cout << '\n';
}

// ----------------------------------------------------------------------------
int main() {
    std::vector<int> data = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};

    // ================================================================
    // 1. filter  —— 按謂詞過濾,保留滿足條件的元素
    // ================================================================
    {
        auto even = data | v::filter([](int x) { return x % 2 == 0; });
        print_range("filter(偶數(shù))", even);  // 2 4 6 8 10
    }

    // ================================================================
    // 2. transform —— 對每個元素施加映射函數(shù)
    // ================================================================
    {
        auto squared = data | v::transform([](int x) { return x * x; });
        print_range("transform(平方)", squared);  // 1 4 9 16 25 36 49 64 81 100
    }

    // ================================================================
    // 3. 管道組合:filter + transform —— 惰性求值,單次遍歷
    // ================================================================
    {
        auto pipeline = data
            | v::filter([](int x) { return x % 2 == 0; })       // 先過濾偶數(shù)
            | v::transform([](int x) { return x * x; });        // 再平方
        print_range("filter + transform(偶數(shù)的平方)", pipeline); // 4 16 36 64 100
    }

    // ================================================================
    // 4. take(n) —— 取前 n 個元素,達(dá)到 n 個后立即停止遍歷
    //    drop(n) —— 跳過前 n 個元素
    // ================================================================
    {
        auto first3 = data | v::take(3);
        print_range("take(3)", first3);  // 1 2 3

        auto skip3 = data | v::drop(3);
        print_range("drop(3)", skip3);   // 4 5 6 7 8 9 10

        // 與 filter 組合:取前3個偶數(shù)
        auto first3even = data
            | v::filter([](int x) { return x % 2 == 0; })
            | v::take(3);
        print_range("前3個偶數(shù)", first3even);  // 2 4 6
    }

    // ================================================================
    // 5. take_while —— 取滿足條件的連續(xù)前綴
    //    drop_while —— 丟棄滿足條件的連續(xù)前綴
    // ================================================================
    {
        auto prefix = data | v::take_while([](int x) { return x < 5; });
        print_range("take_while(x < 5)", prefix);  // 1 2 3 4

        auto suffix = data | v::drop_while([](int x) { return x < 5; });
        print_range("drop_while(x < 5)", suffix);  // 5 6 7 8 9 10
    }

    // ================================================================
    // 6. reverse —— 反轉(zhuǎn) range(要求 bidirectional_range)
    // ================================================================
    {
        auto reversed = data | v::reverse;
        print_range("reverse", reversed);  // 10 9 8 7 6 5 4 3 2 1
    }

    // ================================================================
    // 7. split —— 按分隔符切割 range
    //    返回的是一個 range of ranges,每個子 range 是一段
    // ================================================================
    {
        std::string text = "hello world cpp ranges";
        auto words = text | v::split(' ');
        std::cout << "split(' '): ";
        for (auto word : words) {
            std::cout << '\'';
            for (char ch : word) std::cout << ch;
            std::cout << "' ";
        }
        std::cout << '\n';  // 'hello' 'world' 'cpp' 'ranges'
    }

    // ================================================================
    // 8. join —— 展平嵌套的 range(range of ranges → flat range)
    // ================================================================
    {
        std::vector<std::vector<int>> nested = {{1, 2}, {3, 4, 5}, {6}};
        auto flat = nested | v::join;
        print_range("join(展平嵌套)", flat);  // 1 2 3 4 5 6

        // join 與 split 配合:先切割再展平(類似于去除分隔符)
        std::string text = "a-b-c";
        auto parts = text | v::split('-');
        // 把 '-' 替換為 ' '
        // 注意:這里 split 產(chǎn)生的 subrange 再 join 需要 C++23 的 join_with
        // 此處演示 join 的基本用法
    }

    // ================================================================
    // 9. keys / values —— 提取關(guān)聯(lián)容器的鍵/值
    // ================================================================
    {
        std::map<int, std::string> m = {{1, "one"}, {2, "two"}, {3, "three"}};

        std::cout << "keys: ";
        for (auto k : m | v::keys) std::cout << k << ' ';     // 1 2 3
        std::cout << '\n';

        std::cout << "values: ";
        for (auto v : m | v::values) std::cout << v << ' ';   // one two three
        std::cout << '\n';
    }

    // ================================================================
    // 10. all —— 將任意 range 包裝為 view
    //     當(dāng)你想使用管道語法但手上的容器不是 view 時,all 是橋梁
    // ================================================================
    {
        auto v = data | v::all;          // vector → view
        auto r = v | v::reverse;         // 管道串聯(lián)
        print_range("all | reverse", r); // 10 9 8 7 6 5 4 3 2 1
        // 實際上 | 運算符已經(jīng)隱式做了這個轉(zhuǎn)換,顯式使用 all 的場景較少
    }

    // ================================================================
    // 11. common —— 將 sentinel 類型與 iterator 類型統(tǒng)一
    //     某些遺留代碼要求 begin() 和 end() 返回相同類型
    // ================================================================
    {
        auto filtered = data | v::filter([](int x) { return x > 5; });
        // filtered 的 begin() 和 end() 類型不同(sentinel != iterator)
        // static_assert(!r::common_range<decltype(filtered)>);

        auto common = filtered | v::common;
        // common 的 begin() 和 end() 返回相同類型
        static_assert(r::common_range<decltype(common)>);

        print_range("common", common);  // 6 7 8 9 10
    }

    // ================================================================
    // 12. 投射(Projection) —— 不是適配器,但常與 Range 算法配合
    //     所有 std::ranges 算法都支持 projection 參數(shù)
    // ================================================================
    {
        struct Person { std::string name; int age; };
        std::vector<Person> people = {
            {"Charlie", 35}, {"Alice", 30}, {"Bob", 25}
        };

        // 按年齡排序,使用 projection 而非手寫 lambda
        r::sort(people, std::less{}, &Person::age);

        std::cout << "projection(按age排序): ";
        for (auto& p : people) std::cout << p.name << '(' << p.age << ") ";
        std::cout << '\n';
    }

    return 0;
}

工廠視圖

自身生成 range

工廠功能典型場景
iota(start)無限遞增序列 [start, ∞)配合 take 生成索引
iota(start, end)有限遞增序列 [start, end)生成數(shù)值區(qū)間
empty<T>空 range占位/空結(jié)果
single(x)只包含單一元素的 range插入單元素到管道
istream<T>(stream)從輸入流惰性讀取處理大數(shù)據(jù)文件
counted(it, n)迭代器 + 計數(shù)構(gòu)造 range對接指針+長度 API

代碼示例:

#include <iostream>
#include <ranges>
#include <vector>
#include <string>
#include <sstream>
#include <iterator>
#include <cassert>
namespace r = std::ranges;
namespace v = std::views;
template<typename R>
void print_range(std::string_view name, R&& r) {
    std::cout << name << ": ";
    for (auto&& e : r) std::cout << e << ' ';
    std::cout << '\n';
}
// ----------------------------------------------------------------------------
int main() {
    // ================================================================
    // 1. iota —— 生成遞增序列,類似 Python 的 range()
    //    語法: v::iota(start, end)  生成 [start, end) 的整數(shù)
    //    也可: v::iota(start)       生成 [start, ∞) 的無界序列
    // ================================================================
    {
        // 有界 iota:指定上限
        auto seq = v::iota(1, 11);        // 1, 2, 3, ..., 10
        print_range("iota(1, 11)", seq);  // 1 2 3 4 5 6 7 8 9 10
        // 無界 iota:從某個值開始,無限延伸(必須配合 take 使用)
        // 直接迭代無界 iota 會導(dǎo)致無限循環(huán)!
        auto inf_seq = v::iota(100);               // 100, 101, 102, ...
        auto first5 = inf_seq | v::take(5);
        print_range("iota(100) | take(5)", first5); // 100 101 102 103 104
    }
    // ================================================================
    // 1b. iota 不只是整數(shù) —— 任何支持 ++ 和 < 的類型都可用
    // ================================================================
    {
        // 生成大寫字母序列
        auto alpha = v::iota('A', 'H');     // A, B, C, D, E, F, G
        std::cout << "iota('A','H'): ";
        for (char c : alpha) std::cout << c << ' ';
        std::cout << '\n';
    }
    // ================================================================
    // 2. empty<T> —— 生成空 range(不包含任何元素)
    //    常用于需要"空結(jié)果"占位的場景
    // ================================================================
    {
        auto e = v::empty<int>;
        std::cout << "empty<int> size: " << r::distance(e) << '\n'; // 0
        assert(r::empty(e));  // 確認(rèn)是空 range
    }
    // ================================================================
    // 3. single(x) —— 生成只包含單一元素的 range
    //    常與 join 配合使用,將單元素插入管道流
    // ================================================================
    {
        auto s = v::single(42);
        print_range("single(42)", s);  // 42
        static_assert(r::size(s) == 1);
        assert(*s.begin() == 42);
    }
    // ================================================================
    // 4. istream<T> —— 從輸入流讀取,作為 range
    //    按需從流中惰性讀取,不一次性加載所有數(shù)據(jù)
    // ================================================================
    {
        std::istringstream iss("10 20 30 40 50");
        auto numbers = v::istream<int>(iss);
        std::cout << "istream<int>: ";
        for (int x : numbers) std::cout << x << ' ';  // 10 20 30 40 50
        std::cout << '\n';
    }
    // ================================================================
    // 4b. istream 管道組合 —— 從流讀取后立即過濾/變換
    //     無需先存到 vector,直接惰性處理
    // ================================================================
    {
        std::istringstream iss("1 2 3 4 5 6 7 8 9 10");
        auto result = v::istream<int>(iss)
            | v::filter([](int x) { return x % 2 == 0; })
            | v::transform([](int x) { return x * x; })
            | v::take(3);
        std::cout << "istream管道(偶數(shù)的平方前3個): ";
        for (int x : result) std::cout << x << ' ';  // 4 16 36
        std::cout << '\n';
    }
    // ================================================================
    // 5. counted —— 從迭代器 + 計數(shù)構(gòu)造 range
    //    接收 (iterator, count) 對,生成大小固定的 range
    //    常用于處理遺留代碼中"指針+長度"的 API
    // ================================================================
    {
        std::vector<int> v = {10, 20, 30, 40, 50, 60, 70, 80};
        // 從第3個元素(30)開始,取4個
        auto sub = v::counted(v.begin() + 2, 4);
        print_range("counted(begin+2, 4)", sub);  // 30 40 50 60
        // 實質(zhì)等價于 r::subrange(begin, begin + count)
    }
    // ================================================================
    // 6. 綜合示例:工廠 + 適配器 構(gòu)建完整管道
    //    生成前20個自然數(shù),保留3的倍數(shù),平方后取前5個
    // ================================================================
    {
        auto pipeline = v::iota(1)                     // 工廠: 1,2,3,...
            | v::filter([](int x) { return x % 3 == 0; })  // 保留3的倍數(shù): 3,6,9,...
            | v::transform([](int x) { return x * x; })     // 平方: 9,36,81,...
            | v::take(5);                                   // 取前5個
        print_range("綜合管道", pipeline);  // 9 36 81 144 225
    }
    // ================================================================
    // 6b. 綜合示例:斐波那契數(shù)列生成
    //     利用 iota 和 transform 可以生成任意序列
    // ================================================================
    {
        // 技巧: iota(0) 提供索引 n=0,1,2,...,transform 將 n 映射為 Fib(n)
        // 但這里需要狀態(tài),用單行管道做不直觀,展示另一種思路:
        // 用 iota 產(chǎn)生索引,通過迭代計算 Fib
        // 更直接的 Fibonacci:使用結(jié)構(gòu)化綁定 + iota
        auto fib = v::iota(0)
            | v::transform([a = 0ull, b = 1ull](int) mutable {
                  auto result = a;
                  a = b;
                  b = result + b;
                  return result;
              })
            | v::take(10);
        std::cout << "Fibonacci(前10項): ";
        for (auto f : fib) std::cout << f << ' ';  // 0 1 1 2 3 5 8 13 21 34
        std::cout << '\n';
    }
    return 0;
}

綜合實踐

按部分篩選員工然后加薪資

#include <algorithm>
#include <iomanip>
#include <iostream>
#include <map>
#include <ranges>
#include <string>
#include <vector>
namespace r = std::ranges;
namespace v = std::views;
// ============================================================================
// 員工薪資分析系統(tǒng) — C++20 Ranges 綜合應(yīng)用
// ============================================================================
struct Employee {
    std::string name;
    std::string department;
    double salary;
};
// ============================================================================
// 功能1: 按部門分組統(tǒng)計平均薪資
// ============================================================================
// C++20 沒有 std::views::group_by(那是 C++23 的特性),因此采用 map 聚合,
// 配合 range-based for 遍歷。每個部門的 salary 被累加后求均值。
void avgSalaryByDept(const std::vector<Employee>& employees) {
    // <部門, {薪資總和, 人數(shù)}>
    std::map<std::string, std::pair<double, int>> dept_stats;
    for (const auto& emp : employees) {
        auto& [total, count] = dept_stats[emp.department];
        total += emp.salary;
        ++count;
    }
    std::cout << "\n===== 各部門平均薪資 =====\n";
    std::cout << std::left;
    for (const auto& [dept, stats] : dept_stats) {
        const auto& [total, count] = stats;
        std::cout << "  " << std::setw(12) << dept
                  << " : " << std::fixed << std::setprecision(2)
                  << total / count << '\n';
    }
}
// ============================================================================
// 功能2: 找出薪資最高的員工
// ============================================================================
// 使用 std::ranges::max_element,通過 projection 指定比較對象為 salary 成員。
// 比傳統(tǒng) lambda 版本更簡潔: r::max_element(v, less{}, &Employee::salary)
void findHighestPaid(const std::vector<Employee>& employees) {
    auto it = r::max_element(employees, std::less{}, &Employee::salary);
    std::cout << "\n===== 薪資最高員工 =====\n";
    if (it == employees.end()) {
        std::cout << "  (無數(shù)據(jù))\n";
        return;
    }
    std::cout << "  " << it->name
              << " (" << it->department << ")"
              << " : " << std::fixed << std::setprecision(2)
              << it->salary << '\n';
}
// ============================================================================
// 功能3: 篩選技術(shù)部員工并加薪10%,然后打印
// ============================================================================
// filter 視圖篩選技術(shù)部,展開 for 循環(huán)中修改 salary 后輸出新舊對比。
// 注意: filter 返回的是 view,對 view 中元素的修改會反映回原容器。
void raiseITDept(std::vector<Employee>& employees) {
    std::cout << "\n===== 技術(shù)部加薪10% =====\n";
    std::cout << std::left;
    // 管道: 保留技術(shù)部 → 遍歷修改
    auto it_emps = employees
        | v::filter([](const Employee& e) { return e.department == "技術(shù)部"; });
    for (auto& emp : it_emps) {
        double old_salary = emp.salary;
        emp.salary *= 1.10;
        std::cout << "  " << std::setw(10) << emp.name
                  << " : " << std::setw(8) << old_salary
                  << " -> " << std::fixed << std::setprecision(2)
                  << emp.salary << '\n';
    }
}
// ============================================================================
// 統(tǒng)一入口: 依次執(zhí)行上述三項分析
// ============================================================================
void analyzeEmployees(std::vector<Employee>& employees) {
    avgSalaryByDept(employees);
    findHighestPaid(employees);
    raiseITDept(employees);
}
// ============================================================================
// main
// ============================================================================
int main() {
    std::vector<Employee> staff = {
        {"張三",   "技術(shù)部", 25000.0},
        {"李四",   "技術(shù)部", 28000.0},
        {"王五",   "技術(shù)部", 22000.0},
        {"趙六",   "市場部", 18000.0},
        {"孫七",   "市場部", 20000.0},
        {"周八",   "人事部", 15000.0},
        {"吳九",   "技術(shù)部", 35000.0},
        {"鄭十",   "人事部", 16000.0},
        {"馮十一", "市場部", 19000.0},
    };
    std::cout << std::fixed << std::setprecision(2);
    std::cout << "===== 員工薪資分析系統(tǒng) =====\n";
    std::cout << "共 " << staff.size() << " 名員工\n";
    analyzeEmployees(staff);
}

本期內(nèi)容到這里就結(jié)束了,喜歡請點個贊謝謝

到此這篇關(guān)于C++20新特性之Range庫的文章就介紹到這了,更多相關(guān)C++20 Range庫內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • C語言在linux下編程詳解

    C語言在linux下編程詳解

    這篇文章主要介紹了linux下基于C語言的編程,實例分析了基本使用技巧與相關(guān)概念,具有一定參考借鑒價值,需要的朋友可以參考下
    2021-08-08
  • C++ class和struct到底有什么區(qū)別詳解

    C++ class和struct到底有什么區(qū)別詳解

    這篇文章主要介紹了C++ class和struct到底有什么區(qū)別詳解,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2021-03-03
  • C++實現(xiàn)LeetCode(203.移除鏈表元素)

    C++實現(xiàn)LeetCode(203.移除鏈表元素)

    這篇文章主要介紹了C++實現(xiàn)LeetCode(203.移除鏈表元素),本篇文章通過簡要的案例,講解了該項技術(shù)的了解與使用,以下就是詳細(xì)內(nèi)容,需要的朋友可以參考下
    2021-08-08
  • C++快速排序算法簡明理解

    C++快速排序算法簡明理解

    快速排序由于排序效率在同為O(N*logN)的幾種排序方法中效率較高,因此經(jīng)常被采用,再加上快速排序思想----分治法也確實實用,因此很多軟件公司的筆試面試,包括像騰訊,微軟等知名IT公司都喜歡考這個,還有大大小的程序方面的考試如軟考,考研中也常常出現(xiàn)快速排序的身影
    2022-05-05
  • 華為云CodeArts?IDE?Online快速入門和使用

    華為云CodeArts?IDE?Online快速入門和使用

    華為云CodeArts?IDE?Online服務(wù),提供了可隨時隨地編碼的云上開發(fā)環(huán)境,同時具備開放的生態(tài)和獨立插件市場,本文主要介紹了華為云CodeArts?IDE?Online快速入門和使用,具有一定的參考價值,感興趣的可以了解一下
    2023-08-08
  • C語言預(yù)處理詳解

    C語言預(yù)處理詳解

    這篇文章主要給大家介紹了關(guān)于C語言之預(yù)處理的相關(guān)資料,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2021-10-10
  • C/C++使用過程中的溢出問題詳解

    C/C++使用過程中的溢出問題詳解

    在C/C++程序里有一類非常典型的問題,那就是:溢出問題,現(xiàn)在分別來分析一下常見的數(shù)組溢出,整數(shù)溢出,緩沖區(qū)溢出,棧溢出和指針溢出等,需要的朋友可以參考下
    2024-01-01
  • strcpy函數(shù)實現(xiàn)簡示例命分享

    strcpy函數(shù)實現(xiàn)簡示例命分享

    這篇文章主要介紹了strcpy函數(shù)實現(xiàn)簡示例命,需要的朋友可以參考下
    2014-03-03
  • C++聲明extern變量和extern函數(shù)的用法

    C++聲明extern變量和extern函數(shù)的用法

    extern關(guān)鍵字可以用來聲明變量和函數(shù)作為外部變量或者外部函數(shù)供其它文件使用,所以本文給大家介紹了C++聲明extern變量和extern函數(shù)的用法,文中有相關(guān)的代碼示例供大家參考,需要的朋友可以參考下
    2024-11-11
  • C++從序列容器中刪除元素的四種方法

    C++從序列容器中刪除元素的四種方法

    刪除元素的方法在序列容器和關(guān)聯(lián)容器之間是非常不同的,在序列容器中,vector 和 string 是最常用的,但這里也會介紹 deque 和 list 以供全面了解,盡管在一般情況下可能不會使用它們,本文將詳細(xì)給大家介紹一下C++從序列容器中刪除元素的四種方法,需要的朋友可以參考下
    2025-03-03

最新評論

彰化市| 永寿县| 文登市| 新宁县| 文水县| 蓬莱市| 定远县| 周宁县| 北海市| 济阳县| 茌平县| 呼和浩特市| 醴陵市| 天等县| 民勤县| 忻城县| 利津县| 霍邱县| 天峻县| 东乌珠穆沁旗| 西宁市| 广河县| 定陶县| 清原| 邵武市| 叙永县| 丰原市| 阜新市| 松溪县| 宜春市| 周口市| 商河县| 邵阳市| 汉寿县| 新宁县| 永靖县| 青铜峡市| 东乌珠穆沁旗| 仪陇县| 宁乡县| 江北区|