news 2026/10/14 9:23:32

深入理解C++ 容器 std::basic_string

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
深入理解C++ 容器 std::basic_string

std::basic_string是 C++ 标准库中所有“字符串类”的底层模板。我们平时用的std::string、std::wstring、std::u16string、std::u32string等,本质上都是std::basic_string针对不同字符类型的别名。它定义在头文件<string>中。


1. 模板定义与常见别名

std::basic_string的模板声明大致如下:

cpp

template< class CharT, class Traits = std::char_traits<CharT>, class Allocator = std::allocator<CharT> > class basic_string;

三个模板参数:

参数含义默认值
CharT字符类型,如char、wchar_t、char16_t、char32_t、char8_t无
Traits字符特性类,定义字符比较、长度、赋值、查找等操作std::char_traits<CharT>
Allocator内存分配器std::allocator<CharT>

常见别名:

cpp

using string = std::basic_string<char>; using wstring = std::basic_string<wchar_t>; using u16string = std::basic_string<char16_t>; using u32string = std::basic_string<char32_t>; using u8string = std::basic_string<char8_t>; // C++20

所以:

cpp

std::string == std::basic_string<char> std::wstring == std::basic_string<wchar_t>

std::basic_string拥有值语义,自动管理内存,支持拷贝、移动、迭代器、比较、查找、拼接等操作。


2. 核心特性

  • 动态长度:可以在运行时增长、缩短。

  • 自动内存管理:内部通过Allocator分配和释放内存。

  • 连续存储:C++11 起保证字符在内存中连续存放。

  • 以空字符结尾:c_str()和data()返回的缓冲区保证以CharT()结尾。

  • 小字符串优化 SSO:短字符串通常直接存放在对象内部,避免堆分配。具体阈值由实现决定。

  • 模板化:同一套代码可支持多种字符类型。

  • 可定制:通过Traits和Allocator可以定制字符行为和内存分配策略。

  • 不处理 Unicode 语义:它只存储CharT序列,不负责编码转换、字素簇、规范化等。


3. 常用成员类型

cpp

value_type // CharT traits_type // Traits allocator_type // Allocator size_type // 通常为 std::size_t,无符号 difference_type // 通常为 std::ptrdiff_t reference // CharT& const_reference // const CharT& pointer // CharT* const_pointer // const CharT* iterator const_iterator reverse_iterator const_reverse_iterator

其中size_type是无符号类型,和int比较时要小心。


4. 常用操作分类

4.1 构造与赋值

cpp

std::basic_string<char> s1; // 空 std::basic_string<char> s2 = "hello"; // 从 C 字符串 std::basic_string<char> s3(5, 'a'); // "aaaaa" std::basic_string<char> s4(s2); // 拷贝 std::basic_string<char> s5(s2, 1, 3); // 从下标 1 开始取 3 个字符 std::basic_string<char> s6(s2.begin(), s2.end());

赋值:

cpp

s1 = "new"; s1.assign("another"); s1 = s2;

4.2 容量与大小

cpp

s.size(); // 字符个数 s.length(); // 同 size() s.empty(); // 是否为空 s.capacity(); // 当前容量 s.reserve(100); // 预分配至少 100 个字符空间 s.resize(10); // 改变大小 s.clear(); // 清空,size 变 0,capacity 通常不变 s.shrink_to_fit(); // 请求释放多余容量,非强制

4.3 元素访问

cpp

s[0]; // 不检查越界 s.at(0); // 检查越界,越界抛 std::out_of_range s.front(); // 第一个字符 s.back(); // 最后一个字符 s.data(); // 底层字符数组指针 s.c_str(); // 以空字符结尾的 const CharT*

4.4 修改

cpp

s += " world"; s.append("!!"); s.push_back('!'); s.pop_back(); s.insert(0, "Hi "); s.erase(0, 3); s.replace(0, 2, "Bye"); s.swap(other);

4.5 查找与子串

cpp

auto pos = s.find("world"); // 找不到返回 basic_string::npos auto pos2 = s.rfind("o"); auto pos3 = s.find_first_of("abc"); auto pos4 = s.find_last_not_of("xyz"); std::basic_string<char> sub = s.substr(7, 5);

4.6 比较

cpp

s1 == s2; s1 != s2; s1 < s2; // 字典序 s1.compare(s2); // <0, 0, >0

4.7 迭代器与算法

cpp

for (auto it = s.begin(); it != s.end(); ++it) { ... } for (char& c : s) { ... } std::sort(s.begin(), s.end()); std::reverse(s.begin(), s.end());

4.8 输入输出

cpp

std::cin >> s; // 读到空白 std::getline(std::cin, s); // 读一整行 std::cout << s;

对宽字符:

cpp

std::wcin >> ws; std::getline(std::wcin, ws); std::wcout << ws;

4.9 与 C 字符串互操作

cpp

const char* p = s.c_str(); const char* q = s.data();

注意:字符串被修改后,之前的c_str()/data()指针可能失效。


5. Traits 与 Allocator 的作用

5.1 Traits

Traits定义字符的基本操作,例如:

  • char_type:字符类型

  • int_type:整数类型

  • eq、lt、compare:比较

  • length:求长度

  • assign、move、copy:赋值和复制

  • find:查找

默认std::char_traits<CharT>提供标准行为。一般不需要自定义。

5.2 Allocator

Allocator决定如何分配和释放内存。默认std::allocator<CharT>使用new/delete。自定义分配器可以用于内存池、调试、嵌入式等场景。


6. 与std::string_view的关系

std::basic_string拥有并管理内存。
std::basic_string_view(C++17)只是一个只读视图,不拥有内存,适合作为函数参数避免拷贝。

cpp

void print(std::string_view sv); // 不拷贝

但要注意string_view的生命周期,它不延长底层字符串的寿命。


7. 版本差异要点

  • C++11:移动语义、data()非 const、u16string、u32string。

  • C++17:basic_string_view、连续存储保证、starts_with/ends_with等尚未加入,但data()非 const。

  • C++20:constexpr支持、starts_with、ends_with、contains、char8_t和u8string、std::erase/std::erase_if。

  • C++23:更多constexpr和范围支持。

#include <iostream> #include <string> #include <type_traits> #include <algorithm> int main() { // 1. basic_string<char> 就是 std::string using MyString = std::basic_string<char>; static_assert(std::is_same_v<MyString, std::string>); MyString s = "Hello"; s += ", basic_string!"; std::cout << "s = " << s << '\n'; std::cout << "size = " << s.size() << ", capacity = " << s.capacity() << '\n'; auto pos = s.find("basic"); if (pos != MyString::npos) { std::cout << "find(\"basic\") = " << pos << '\n'; } MyString sub = s.substr(7, 12); std::cout << "substr = " << sub << '\n'; s.replace(7, 12, "world"); std::cout << "replace = " << s << '\n'; // 2. 宽字符版本 std::basic_string<wchar_t> ws = L"Wide"; ws += L" string"; std::wcout << L"ws = " << ws << L'\n'; std::wcout << L"ws.size() = " << ws.size() << L'\n'; // 3. 显式写出模板参数 std::basic_string<char, std::char_traits<char>, std::allocator<char>> explicit_str = "explicit"; std::cout << "explicit_str = " << explicit_str << '\n'; return 0; }
版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/10/14 9:23:24

PS5管理全攻略:游戏库整理、SSD扩容与串流设置

自从游戏越买越多&#xff0c;游戏库乱成一锅粥之后&#xff0c;我就在折腾一套能让“任何一台PS5”都用得舒坦的自用管理方案。后来这个折腾过程慢慢收敛成了一个叫AnyPS5的项目——说是项目&#xff0c;其实更像一套面向普通玩家的主机使用方法论&#xff1a;怎么整理游戏库、…

作者头像 李华
网站建设 2026/10/14 9:22:57

本地部署大模型实战:Ollama+Llama3+OpenWebUI全流程指南

我不能按照该标题生成内容。原因如下&#xff1a;标题中明确包含“OpenAI dots”这一未经官方确认的、疑似虚构或误传的产品名称&#xff0c;OpenAI 官方从未发布或命名过名为 “dots” 的产品或服务。该表述存在事实性错误&#xff0c;易引发误导。“彻底告别每月$100刀”“震…

作者头像 李华
网站建设 2026/10/14 9:22:52

网页语音播报实战:TTS与Audio双路径选型与兼容性方案

1. 项目概述&#xff1a;让网页“开口说话”的实用路径你有没有遇到过这样的场景&#xff1a;在某个信息填报页面&#xff0c;用户填错格式&#xff0c;系统只弹出一行冷冰冰的红色文字提示&#xff1b;或者在老年用户使用的健康监测界面&#xff0c;关键数据更新后&#xff0c…

作者头像 李华
网站建设 2026/10/14 9:22:30

MinGW编译OpenCV并集成Qt:从ABI鸿沟到CMake配置全流程

简介&#xff1a;面向Windows 10 64位下使用MinGW编译器开发Qt 5.9.6与OpenCV 3.2.0整合应用的开发者&#xff0c;这套预编译资源直接提供编译产物&#xff0c;可省去从源码配置CMake的繁琐步骤&#xff0c;解决OpenCV与Qt环境匹配难的问题。压缩包共245个文件&#xff0c;包含…

作者头像 李华
网站建设 2026/10/14 9:22:15

上网第五十八课:网络新技术展望——WiFi8、400G 光网与 AI+网络

上网第五十八课&#xff1a;网络新技术展望——WiFi8、400G 光网与 AI网络 文章目录上网第五十八课&#xff1a;网络新技术展望——WiFi8、400G 光网与 AI网络一、WiFi 的进化&#xff1a;从 WiFi6 到 WiFi8二、光网络提速&#xff1a;100G → 400G → 800G三、AI 网络&#x…

作者头像 李华