37 C++ STL模板库6-string_view

发布于:2025-08-15 ⋅ 阅读:(11) ⋅ 点赞:(0)

C++ STL模板库6-string_view


string_view是一种轻量级的字符串视图机制。 string_view不管理内存,它只是现有字符串数据的视图或引用。避免了不必要的内存分配和复制。
std::string_view是 C++17 标准引入的 STL 核心组件,定义于头文件 <string_view> 中,属于标准模板库(STL)的正式成员。

定义特性 🧩

定义位置 : <string_view> 头文件
命名空间 : std 命名空间下(与 std::string 同级)
模板类型 : 类模板:basic_string_view<charT, traits> → 特化 string_viewchar

  • 非拥有式视图:仅持有原始字符串的指针和长度,不管理内存

    • 需确保底层字符串生命周期长于 string_view
  • 零拷贝开销 🚀

    • 操作成本等价于裸指针操作(编译期优化)

    • 构造、子串操作,性能远优于 std::string 的复制操作

      // 使用 std::string(触发复制)
      std::string s = large_text;
      auto sub = s.substr(0, 30); // O(n) 复制开销 
      
      // 使用 std::string_view(零拷贝)
      std::string_view sv(large_text);
      auto sub_view = sv.substr(0, 30); // O(1) 仅设置指针和长度
      
  • 兼容多种字符串类型

    • std::string, const char*, char[] 自动兼容

      #include <string_view>
      
      // 典型STL用法:构造string_view对象 
      std::string str = "Hello STL";
      std::string_view sv(str);  // 指向str数据的视图
      

常用操作 ⚙️

  1. 构造与赋值

    std::string_view sv;          // 空视图 
    std::string_view sv("Text");  // 直接初始化
    sv = other_sv;                // 赋值(浅拷贝)
    
  2. 元素访问

    • sv[i]:无边界检查,高效但不安全。
    • sv.at(i):越界抛 std::out_of_range 异常。
    • sv.front() / sv.back():首尾字符 。
  3. 大小与容量

    • sv.size() / sv.length():字符数(不含 \0)。
    • sv.empty():判断是否为空视图。
  4. 子串操作

    sv.substr(start_pos, length); // O(1) 复杂度,返回新视图 
    
  5. 查找与比较

    • sv.find("sub"):返回子串首次出现位置(失败时为 sv.npos)。
    • sv.compare(other_sv):字典序比较(返回 0/正/负数)

使用注意事项⚠

  1. 生命周期管理

    • 严禁持有临时字符串的视图(如函数返回的临时 std::string
    auto bad_view = std::string_view(std::string("temp")); // 错误!临时对象销毁后视图无效
    
    std::string_view create_view() {
       std::string temp = "Temporary";
       return std::string_view(temp);  // 错误!temp析构后视图失效 
    }  // ❌ 返回悬垂指针 
    
  2. 无终止符

    • 不以 \0 结尾,需通过 size() 确定长度。传递到 C API 时可用 sv.data(),但需确保字符串本身有终止符。
    char buf[] = {'A','B'};  // 不以\0结尾 
    std::string_view sv(buf, 2);
    std::cout << sv;  // 安全(明确长度)
    // ❌ 错误:printf(sv.data()); // 可能越界 
    
  3. 修改限制

    • 不可通过视图修改底层字符串内容(设计为只读视图)。
    sv.remove_prefix(3);  // ✅ 移动视图起点(string无此操作)
    sv.data()[sv.size()] = '\0';  // ❌ 非法写入(非可修改内存)
    

应用场景

  1. 函数参数传递

    • 替代 const std::string&const char*,避免隐式转换和复制:

      void process(std::string_view data); // 接收任意字符串类型
      
  2. 解析大文本

    • 处理日志或文件时,用 string_view 截取子串无需复制内存。
      解析大文本的子串,优先用 std::string_view代替std::string::substr
  3. 兼容旧代码接口现代化

    • 可隐式转换为 const char*(需确保有终止符),适配传统 C 接口。
    // 传统接口(引发拷贝)
    void process(const std::string& str);  
    
    // 现代接口(兼容所有字符串类型)
    void process(std::string_view str);  // ✅ 接受string/char*/字面量 
    

网站公告

今日签到

点亮在社区的每一天
去签到