C++ Primer 第17章:标准库特殊设施


17.1 tuple 类型

17.1.1 tuple 基础

tuple 是 pair 的泛化:
pair  → 两个成员
tuple → 任意数量的成员,每个成员可以是不同类型
​
头文件:<tuple>
// tuple_basic.cpp -- tuple基础
#include <iostream>
#include <tuple>
#include <string>
#include <vector>
​
int main()
{
    using namespace std;
​
    // ===== 创建 tuple =====
    tuple<int, string, double> t1(42, "Hello", 3.14);
    auto t2 = make_tuple(42, "Hello", 3.14);   // 推断类型
​
    // C++17 结构化绑定
    auto [i, s, d] = t2;
    cout << i << " " << s << " " << d << endl;
​
    // ===== 访问 tuple 成员 =====
    // get<N>(t):获取第N个成员(从0开始)
    cout << get<0>(t1) << endl;   // 42
    cout << get<1>(t1) << endl;   // Hello
    cout << get<2>(t1) << endl;   // 3.14
​
    // 修改成员
    get<0>(t1) = 100;
    cout << "修改后:" << get<0>(t1) << endl;
​
    // ===== tuple 的大小 =====
    cout << "成员数:" << tuple_size<decltype(t1)>::value << endl;   // 3
​
    // ===== tuple 的成员类型 =====
    tuple_element<1, decltype(t1)>::type str = "World";
    cout << str << endl;
​
    // ===== tuple 的比较 =====
    auto ta = make_tuple(1, 2, 3);
    auto tb = make_tuple(1, 2, 4);
    cout << boolalpha;
    cout << "ta < tb: " << (ta < tb) << endl;   // true
    cout << "ta == tb: " << (ta == tb) << endl; // false
​
    // ===== tuple 的实际应用:返回多个值 =====
    auto getMinMax = [](const vector<int>& v)
        -> tuple<int, int, double>
    {
        int minV = *min_element(v.begin(), v.end());
        int maxV = *max_element(v.begin(), v.end());
        double avg = accumulate(v.begin(), v.end(), 0.0) / v.size();
        return {minV, maxV, avg};
    };
​
    vector<int> nums = {3, 1, 4, 1, 5, 9, 2, 6};
    auto [minV, maxV, avg] = getMinMax(nums);
    cout << "min=" << minV << " max=" << maxV << " avg=" << avg << endl;
​
    return 0;
}

17.1.2 tuple 的高级用法

// tuple_advanced.cpp -- tuple高级用法
#include <iostream>
#include <tuple>
#include <string>
#include <vector>
#include <algorithm>
​
// ===== 用 tuple 实现多键排序 =====
struct Employee
{
    string name;
    int    dept;
    double salary;
};
​
int main()
{
    using namespace std;
​
    vector<Employee> employees = {
        {"张三", 2, 8000},
        {"李四", 1, 9000},
        {"王五", 2, 7500},
        {"赵六", 1, 8500},
        {"钱七", 3, 10000}
    };
​
    // 按部门升序,同部门按薪资降序排序
    sort(employees.begin(), employees.end(),
         [](const Employee& a, const Employee& b) {
             return make_tuple(a.dept, -a.salary) <
                    make_tuple(b.dept, -b.salary);
         });
​
    cout << "排序结果:" << endl;
    for (const auto& e : employees)
        cout << "  部门" << e.dept << " " << e.name
             << " $" << e.salary << endl;
​
    // ===== tuple 拼接 =====
    auto t1 = make_tuple(1, 2, 3);
    auto t2 = make_tuple("a", "b");
    auto t3 = tuple_cat(t1, t2);   // 拼接两个tuple
​
    cout << "\ntuple_cat结果:" << endl;
    cout << get<0>(t3) << " " << get<1>(t3) << " " << get<2>(t3)
         << " " << get<3>(t3) << " " << get<4>(t3) << endl;
​
    // ===== tie:解包 tuple =====
    int a, b, c;
    tie(a, b, c) = make_tuple(10, 20, 30);
    cout << "\ntie解包:" << a << " " << b << " " << c << endl;
​
    // 忽略某些成员
    tie(a, ignore, c) = make_tuple(100, 200, 300);
    cout << "忽略中间:" << a << " " << c << endl;
​
    return 0;
}

17.2 bitset 类型

// bitset_demo.cpp -- bitset详解
#include <iostream>
#include <bitset>
#include <string>
​
int main()
{
    using namespace std;
​
    // ===== 创建 bitset =====
    bitset<8> b1;              // 8位,全0
    bitset<8> b2(0b10110100);  // 从整数初始化
    bitset<8> b3("10110100");  // 从字符串初始化
    bitset<8> b4(0xFF);        // 255 = 11111111
​
    cout << "b1 = " << b1 << endl;   // 00000000
    cout << "b2 = " << b2 << endl;   // 10110100
    cout << "b3 = " << b3 << endl;   // 10110100
    cout << "b4 = " << b4 << endl;   // 11111111
​
    // ===== 访问位 =====
    cout << "\n访问位:" << endl;
    cout << "b2[0] = " << b2[0] << endl;   // 最低位:0
    cout << "b2[2] = " << b2[2] << endl;   // 1
    cout << "b2[7] = " << b2[7] << endl;   // 最高位:1
​
    // test():检查指定位(有边界检查)
    cout << "b2.test(2) = " << boolalpha << b2.test(2) << endl;
​
    // ===== 修改位 =====
    bitset<8> b = b2;
    b.set(0);      // 将位0置1
    b.reset(7);    // 将位7置0
    b.flip(4);     // 翻转位4
    cout << "\n修改后:" << b << endl;
​
    b.set();       // 所有位置1
    cout << "全1:" << b << endl;
​
    b.reset();     // 所有位置0
    cout << "全0:" << b << endl;
​
    b.flip();      // 翻转所有位
    cout << "翻转:" << b << endl;
​
    // ===== 位运算 =====
    bitset<8> x("10110100");
    bitset<8> y("01101100");
​
    cout << "\n位运算:" << endl;
    cout << "x & y = " << (x & y) << endl;   // 按位与
    cout << "x | y = " << (x | y) << endl;   // 按位或
    cout << "x ^ y = " << (x ^ y) << endl;   // 按位异或
    cout << "~x    = " << (~x)    << endl;   // 按位取反
    cout << "x << 2 = " << (x << 2) << endl; // 左移
    cout << "x >> 2 = " << (x >> 2) << endl; // 右移
​
    // ===== 统计和转换 =====
    cout << "\n统计:" << endl;
    cout << "count(1的个数) = " << x.count() << endl;
    cout << "size(总位数)   = " << x.size()  << endl;
    cout << "any(有1)       = " << x.any()   << endl;
    cout << "all(全1)       = " << x.all()   << endl;
    cout << "none(全0)      = " << x.none()  << endl;
​
    // 转换
    cout << "\n转换:" << endl;
    cout << "to_ulong  = " << x.to_ulong()  << endl;
    cout << "to_ullong = " << x.to_ullong() << endl;
    cout << "to_string = " << x.to_string() << endl;
​
    // ===== 实际应用:权限管理 =====
    cout << "\n===== 权限管理 =====" << endl;
    enum Permission { READ = 0, WRITE = 1, EXECUTE = 2, ADMIN = 3 };
​
    bitset<4> userPerm;
    userPerm.set(READ);
    userPerm.set(WRITE);
​
    cout << "用户权限:" << userPerm << endl;
    cout << "有读权限:" << userPerm.test(READ)    << endl;
    cout << "有执行权限:" << userPerm.test(EXECUTE) << endl;
​
    // 添加权限
    userPerm.set(EXECUTE);
    cout << "添加执行权限后:" << userPerm << endl;
​
    // 删除权限
    userPerm.reset(WRITE);
    cout << "删除写权限后:" << userPerm << endl;
​
    return 0;
}

17.3 正则表达式

// regex_demo.cpp -- 正则表达式
#include <iostream>
#include <regex>
#include <string>
#include <vector>
​
int main()
{
    using namespace std;
​
    // ===== 基本匹配 =====
    cout << "===== 基本匹配 =====" << endl;
​
    string pattern = R"(\d{3}-\d{4}-\d{4})";   // 手机号格式
    regex  re(pattern);
​
    string text = "联系方式:138-1234-5678 或 010-12345678";
​
    // regex_search:在字符串中搜索
    smatch match;
    if (regex_search(text, match, re))
        cout << "找到手机号:" << match[0] << endl;
​
    // regex_match:整个字符串匹配
    string phone = "138-1234-5678";
    cout << "是手机号:" << boolalpha << regex_match(phone, re) << endl;
​
    // ===== 查找所有匹配 =====
    cout << "\n===== 查找所有匹配 =====" << endl;
    string emails = "联系 alice@example.com 或 bob@test.org 获取帮助";
    regex emailRe(R"([a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,})");
​
    sregex_iterator it(emails.begin(), emails.end(), emailRe);
    sregex_iterator end;
    while (it != end)
    {
        cout << "邮箱:" << (*it)[0] << endl;
        ++it;
    }
​
    // ===== 捕获组 =====
    cout << "\n===== 捕获组 =====" << endl;
    string date = "2024-01-15";
    regex dateRe(R"((\d{4})-(\d{2})-(\d{2}))");
    smatch dateMatch;
​
    if (regex_match(date, dateMatch, dateRe))
    {
        cout << "完整匹配:" << dateMatch[0] << endl;
        cout << "年:" << dateMatch[1] << endl;
        cout << "月:" << dateMatch[2] << endl;
        cout << "日:" << dateMatch[3] << endl;
    }
​
    // ===== 替换 =====
    cout << "\n===== 替换 =====" << endl;
    string text2 = "Hello World Hello C++";
    regex helloRe("Hello");
​
    // regex_replace:替换所有匹配
    string result = regex_replace(text2, helloRe, "Hi");
    cout << "替换后:" << result << endl;
​
    // 只替换第一个
    string result2 = regex_replace(text2, helloRe, "Hi",
                                   regex_constants::format_first_only);
    cout << "只替换第一个:" << result2 << endl;
​
    // ===== 分割字符串 =====
    cout << "\n===== 分割字符串 =====" << endl;
    string csv = "apple,banana,,cherry,date";
    regex sepRe(",");
​
    sregex_token_iterator tokIt(csv.begin(), csv.end(), sepRe, -1);
    sregex_token_iterator tokEnd;
    while (tokIt != tokEnd)
    {
        cout << "\"" << *tokIt << "\"" << endl;
        ++tokIt;
    }
​
    // ===== 实际应用:验证输入 =====
    cout << "\n===== 输入验证 =====" << endl;
    auto validate = [](const string& input, const string& pattern,
                       const string& name) {
        regex re(pattern);
        bool valid = regex_match(input, re);
        cout << name << " \"" << input << "\":" << boolalpha << valid << endl;
        return valid;
    };
​
    // 验证邮箱
    validate("user@example.com", R"([a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,})", "邮箱");
    validate("invalid-email", R"([a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,})", "邮箱");
​
    // 验证IP地址
    validate("192.168.1.1", R"((\d{1,3}\.){3}\d{1,3})", "IP地址");
    validate("256.0.0.1",   R"((\d{1,3}\.){3}\d{1,3})", "IP地址");
​
    return 0;
}

17.4 随机数

// random_demo.cpp -- 随机数
#include <iostream>
#include <random>
#include <vector>
#include <map>
#include <iomanip>
#include <algorithm>
​
int main()
{
    using namespace std;
​
    // ===== 随机数引擎 =====
    // 默认随机数引擎
    default_random_engine engine;
​
    // 使用随机设备作为种子(真随机)
    random_device rd;
    default_random_engine engine2(rd());
​
    // 使用时间作为种子
    default_random_engine engine3(time(nullptr));
​
    // ===== 均匀分布 =====
    cout << "===== 均匀分布 =====" << endl;
​
    // 整数均匀分布 [1, 6](模拟骰子)
    uniform_int_distribution<int> dice(1, 6);
    cout << "骰子:";
    for (int i = 0; i < 10; i++)
        cout << dice(engine2) << " ";
    cout << endl;
​
    // 浮点均匀分布 [0, 1)
    uniform_real_distribution<double> prob(0.0, 1.0);
    cout << "概率:";
    for (int i = 0; i < 5; i++)
        cout << fixed << setprecision(3) << prob(engine2) << " ";
    cout << endl;
​
    // ===== 正态分布 =====
    cout << "\n===== 正态分布 =====" << endl;
    normal_distribution<double> normal(0.0, 1.0);   // 均值0,标准差1
​
    // 统计分布
    map<int, int> hist;
    for (int i = 0; i < 10000; i++)
    {
        int bucket = static_cast<int>(round(normal(engine2)));
        hist[bucket]++;
    }
​
    cout << "正态分布直方图:" << endl;
    for (auto& [val, cnt] : hist)
    {
        if (val >= -3 && val <= 3)
        {
            cout << setw(3) << val << " | ";
            cout << string(cnt / 100, '*') << endl;
        }
    }
​
    // ===== 其他分布 =====
    cout << "\n===== 其他分布 =====" << endl;
​
    // 伯努利分布(成功概率0.7)
    bernoulli_distribution bern(0.7);
    int successes = 0;
    for (int i = 0; i < 1000; i++)
        if (bern(engine2)) successes++;
    cout << "伯努利(p=0.7),1000次成功:" << successes << endl;
​
    // 泊松分布(平均值4)
    poisson_distribution<int> poisson(4.0);
    cout << "泊松分布(λ=4):";
    for (int i = 0; i < 10; i++)
        cout << poisson(engine2) << " ";
    cout << endl;
​
    // ===== 随机打乱 =====
    cout << "\n===== 随机打乱 =====" << endl;
    vector<int> v = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
    shuffle(v.begin(), v.end(), engine2);
    cout << "打乱后:";
    for (int x : v) cout << x << " ";
    cout << endl;
​
    // ===== 实际应用:随机抽样 =====
    cout << "\n===== 随机抽样 =====" << endl;
    vector<string> names = {"Alice", "Bob", "Carol", "David",
                            "Eve", "Frank", "Grace", "Henry"};
​
    // 随机选3个
    shuffle(names.begin(), names.end(), engine2);
    cout << "随机选3人:";
    for (int i = 0; i < 3; i++) cout << names[i] << " ";
    cout << endl;
​
    return 0;
}

17.5 IO 库再探

17.5.1 格式化输入输出

// io_format.cpp -- 格式化IO
#include <iostream>
#include <iomanip>
#include <sstream>
#include <string>
​
int main()
{
    using namespace std;
​
    // ===== 整数格式 =====
    cout << "===== 整数格式 =====" << endl;
    int n = 255;
​
    cout << "十进制:" << dec << n << endl;
    cout << "八进制:" << oct << n << endl;
    cout << "十六进制:" << hex << n << endl;
    cout << "十六进制大写:" << uppercase << hex << n << endl;
    cout << dec << nouppercase;   // 恢复
​
    // 显示进制前缀
    cout << showbase;
    cout << "带前缀十进制:" << dec << n << endl;
    cout << "带前缀八进制:" << oct << n << endl;
    cout << "带前缀十六进制:" << hex << n << endl;
    cout << noshowbase << dec;
​
    // 显示正号
    cout << showpos << 42 << " " << -42 << noshowpos << endl;
​
    // ===== 浮点格式 =====
    cout << "\n===== 浮点格式 =====" << endl;
    double pi = 3.14159265358979;
​
    cout << "默认:" << pi << endl;
    cout << fixed << "fixed:" << pi << endl;
    cout << scientific << "scientific:" << pi << endl;
    cout << defaultfloat;
​
    // 精度
    for (int p = 1; p <= 8; p++)
        cout << "precision(" << p << "):" << setprecision(p) << pi << endl;
    cout << setprecision(6);   // 恢复默认
​
    // ===== 宽度和对齐 =====
    cout << "\n===== 宽度对齐 =====" << endl;
    cout << setw(10) << "右对齐" << "|" << endl;
    cout << left << setw(10) << "左对齐" << "|" << endl;
    cout << right;
​
    // 填充字符
    cout << setfill('0') << setw(8) << 42 << endl;   // 00000042
    cout << setfill('*') << setw(10) << "Hi" << endl; // ********Hi
    cout << setfill(' ');   // 恢复
​
    // ===== 格式化表格 =====
    cout << "\n===== 格式化表格 =====" << endl;
    cout << fixed << setprecision(2);
    cout << left
         << setw(12) << "商品"
         << right
         << setw(8)  << "数量"
         << setw(10) << "单价"
         << setw(10) << "小计" << endl;
    cout << string(40, '-') << endl;
​
    struct Item { string name; int qty; double price; };
    Item items[] = {{"苹果", 5, 3.50}, {"香蕉", 12, 1.80}, {"橙子", 8, 4.20}};
​
    double total = 0;
    for (const auto& item : items)
    {
        double subtotal = item.qty * item.price;
        total += subtotal;
        cout << left  << setw(12) << item.name
             << right << setw(8)  << item.qty
             << setw(10) << item.price
             << setw(10) << subtotal << endl;
    }
    cout << string(40, '-') << endl;
    cout << right << setw(30) << "合计:" << setw(10) << total << endl;
​
    return 0;
}

17.5.2 未格式化 IO

// unformatted_io.cpp -- 未格式化IO
#include <iostream>
#include <fstream>
#include <string>
​
int main()
{
    using namespace std;
​
    // ===== 单字节操作 =====
    cout << "===== 单字节操作 =====" << endl;
​
    // get():读取单个字符(含空白)
    char ch;
    cout << "输入字符:";
    cin.get(ch);
    cout << "读取到:'" << ch << "'" << endl;
​
    // peek():查看但不读取
    char next = cin.peek();
    cout << "下一个字符:'" << next << "'" << endl;
​
    // putback():放回字符
    cin.putback(ch);
​
    // unget():撤销最后一次读取
    // cin.unget();
​
    // ===== 多字节操作 =====
    cout << "\n===== 多字节操作 =====" << endl;
​
    // read():读取指定字节数
    char buf[10];
    cin.read(buf, 5);
    buf[5] = '\0';
    cout << "read(5):" << buf << endl;
​
    // gcount():上次读取的字节数
    cout << "gcount:" << cin.gcount() << endl;
​
    // ===== 文件定位 =====
    cout << "\n===== 文件定位 =====" << endl;
​
    // 写入测试文件
    {
        ofstream out("test.bin", ios::binary);
        out << "Hello, World!";
    }
​
    // 读取并定位
    ifstream in("test.bin", ios::binary);
​
    // tellg():获取当前位置
    cout << "初始位置:" << in.tellg() << endl;
​
    // seekg():设置读取位置
    in.seekg(7);   // 从头移动7字节
    cout << "移动到7后:" << in.tellg() << endl;
​
    char c;
    in.get(c);
    cout << "读取到:'" << c << "'" << endl;   // 'W'
​
    // 从末尾定位
    in.seekg(-6, ios::end);
    string rest;
    getline(in, rest);
    cout << "末尾前6字节:" << rest << endl;
​
    return 0;
}

17.6 综合示例:日志分析系统

// log_analyzer.cpp -- 综合示例:日志分析系统
#include <iostream>
#include <fstream>
#include <sstream>
#include <string>
#include <regex>
#include <map>
#include <vector>
#include <tuple>
#include <algorithm>
#include <iomanip>
#include <random>

// 日志条目
struct LogEntry
{
    string timestamp;
    string level;
    string module;
    string message;
};

class LogAnalyzer
{
private:
    vector<LogEntry> entries_;

    // 日志格式:[2024-01-15 10:30:45] [INFO] [Module] Message
    regex logPattern_{
        R"(\[(\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2})\] \[(\w+)\] \[(\w+)\] (.+))"
    };

public:
    // 解析日志文件
    bool parseFile(const string& filename)
    {
        ifstream file(filename);
        if (!file) return false;

        string line;
        while (getline(file, line))
        {
            smatch match;
            if (regex_match(line, match, logPattern_))
            {
                entries_.push_back({
                    match[1], match[2], match[3], match[4]
                });
            }
        }
        return true;
    }

    // 解析字符串
    void parseString(const string& logs)
    {
        istringstream iss(logs);
        string line;
        while (getline(iss, line))
        {
            smatch match;
            if (regex_match(line, match, logPattern_))
            {
                entries_.push_back({
                    match[1], match[2], match[3], match[4]
                });
            }
        }
    }

    // 按级别统计
    map<string, int> countByLevel() const
    {
        map<string, int> counts;
        for (const auto& e : entries_)
            counts[e.level]++;
        return counts;
    }

    // 按模块统计
    map<string, int> countByModule() const
    {
        map<string, int> counts;
        for (const auto& e : entries_)
            counts[e.module]++;
        return counts;
    }

    // 搜索包含关键词的日志
    vector<LogEntry> search(const string& keyword) const
    {
        vector<LogEntry> results;
        regex kw(keyword, regex_constants::icase);
        for (const auto& e : entries_)
            if (regex_search(e.message, kw))
                results.push_back(e);
        return results;
    }

    // 获取错误日志
    vector<LogEntry> getErrors() const
    {
        vector<LogEntry> errors;
        for (const auto& e : entries_)
            if (e.level == "ERROR" || e.level == "CRITICAL")
                errors.push_back(e);
        return errors;
    }

    // 生成报告
    void generateReport(ostream& os) const
    {
        os << "\n" << string(60, '=') << endl;
        os << "日志分析报告" << endl;
        os << string(60, '=') << endl;

        os << "\n总条目数:" << entries_.size() << endl;

        // 级别统计
        os << "\n===== 按级别统计 =====" << endl;
        for (const auto& [level, count] : countByLevel())
            os << setw(10) << level << ": " << count << " 条" << endl;

        // 模块统计
        os << "\n===== 按模块统计 =====" << endl;
        for (const auto& [module, count] : countByModule())
            os << setw(10) << module << ": " << count << " 条" << endl;

        // 错误日志
        auto errors = getErrors();
        if (!errors.empty())
        {
            os << "\n===== 错误日志(" << errors.size() << "条)=====" << endl;
            for (const auto& e : errors)
                os << "[" << e.timestamp << "] [" << e.level << "] "
                   << "[" << e.module << "] " << e.message << endl;
        }
    }
};

// 生成测试日志
string generateTestLogs()
{
    default_random_engine engine(42);
    uniform_int_distribution<int> levelDist(0, 3);
    uniform_int_distribution<int> moduleDist(0, 2);

    vector<string> levels = {"DEBUG", "INFO", "WARNING", "ERROR"};
    vector<string> modules = {"Auth", "Database", "Network"};
    vector<string> messages = {
        "用户登录成功", "数据库连接建立", "网络请求超时",
        "认证失败:密码错误", "查询执行完成", "连接池已满",
        "用户注销", "事务提交成功", "DNS解析失败"
    };

    uniform_int_distribution<int> msgDist(0, messages.size() - 1);

    ostringstream oss;
    for (int i = 0; i < 20; i++)
    {
        int h = 10 + i / 4, m = (i * 15) % 60, s = i * 3 % 60;
        oss << "[2024-01-15 "
            << setfill('0') << setw(2) << h << ":"
            << setw(2) << m << ":"
            << setw(2) << s << "] "
            << "[" << levels[levelDist(engine)] << "] "
            << "[" << modules[moduleDist(engine)] << "] "
            << messages[msgDist(engine)] << "\n";
    }
    return oss.str();
}

int main()
{
    using namespace std;

    LogAnalyzer analyzer;

    // 解析测试日志
    string logs = generateTestLogs();
    cout << "===== 原始日志 =====" << endl;
    cout << logs;

    analyzer.parseString(logs);

    // 生成报告
    analyzer.generateReport(cout);

    // 搜索
    cout << "\n===== 搜索\"失败\" =====" << endl;
    auto results = analyzer.search("失败");
    for (const auto& e : results)
        cout << "[" << e.level << "] " << e.message << endl;

    return 0;
}

📝 第17章知识点总结

知识点 核心要点
tuple make_tuple 创建,get<N> 访问,C++17结构化绑定解包
tuple_size tuple_size<T>::value 获取成员数量
tuple_element tuple_element<N,T>::type 获取第N个成员的类型
tie tie(a,b,c) = t 解包tuple,ignore 忽略某个成员
tuple_cat 拼接多个tuple
bitset 固定大小的位集合,支持位运算,set/reset/flip/test
bitset 统计 count()(1的个数)、any()all()none()
regex regex_match(全匹配)、regex_search(搜索)、regex_replace(替换)
smatch 存储匹配结果,[0]是完整匹配,[1]起是捕获组
sregex_iterator 遍历所有匹配结果
随机数引擎 default_random_engine,用 random_device 或时间作种子
随机数分布 uniform_int_distributionuniform_real_distributionnormal_distribution
格式化IO setw/setprecision/fixed/scientific/left/right/setfill
未格式化IO get/peek/putback/read/gcount/seekg/tellg
Logo

AtomGit 是由开放原子开源基金会联合 CSDN 等生态伙伴共同推出的新一代开源与人工智能协作平台。平台坚持“开放、中立、公益”的理念,把代码托管、模型共享、数据集托管、智能体开发体验和算力服务整合在一起,为开发者提供从开发、训练到部署的一站式体验。

更多推荐