Published on

C++ std::string_view 简介

Authors
  • avatar
    Name
    Vegetog
    Twitter

std::string_view 是 C++17 引入的只读字符串视图。它引用已有的字符,不复制字符,也不拥有底层内存。

可以把它理解为“一个指针 + 一个长度”:指针表示字符串从哪里开始,长度表示需要读取多少个字符。

用途

string_view 主要用于以下场景:

  • 作为只读函数参数:接收 std::string、字符串字面量等,避免不必要的临时字符串构造。
  • 截取子串:只调整引用范围,不复制字符。

简单使用示例

作为函数参数

#include <iostream>
#include <string>
#include <string_view>

void print(std::string_view text) {
    std::cout << text << '\n';
}

int main() {
    std::string s = "hello";

    print(s);
    print("world");
}

两次调用都不需要复制字符串中的字符。string_view 本身很小,通常直接按值传参。

截取子串

std::string s = "hello world";
std::string_view view = s;

auto word = view.substr(6, 5);

std::cout << word; // world

word 直接引用 s 中的 "world",没有创建新的字符副本。与之相比,s.substr(6, 5) 会返回一个新的 std::string。

调整视图范围

std::string_view view = "hello world";

view.remove_prefix(6);
std::cout << view; // world

remove_prefix() 只缩小视图范围,不修改原始字符串。移除的数量不能超过当前视图的长度。

注意事项

1. 底层字符串必须保持有效

// 错误:临时 string 在这一行结束后被销毁
std::string_view view = std::string("hello");

正确写法:

std::string s = "hello";
std::string_view view = s;

使用 view 时,要保证 s 仍然存在。对 s 的修改如果触发内存重新分配,也可能使视图失效。

2. 不能通过视图修改字符

std::string_view view = "hello";

// view[0] = 'H'; // 编译错误

只读指的是不能通过视图修改字符;如果原字符串的字符被修改,视图也会看到变化。

3. 不保证以 '\0' 结尾

std::string_view view = "hello world";
auto word = view.substr(0, 5); // hello

word.data() 指向的仍是原始字符,其后还有 " world",因此不能直接当作独立的 C 风格字符串使用。如果需要,可以创建一个拥有自己内存的字符串:

std::string owned(word);

只需要读取已有字符时,可以使用 std::string_view;需要保存独立数据或修改字符串时,使用 std::string。