# std::basic_string

< cpp‎ | string

定义于头文件 `<string>` |  |
template< class CharT, class Traits = std::char_traits<CharT>, class Allocator = std::allocator<CharT> > class basic_string; | (1) |
namespace pmr { template <class CharT, class Traits = std::char_traits<CharT>> using basic_string = std::basic_string< CharT, Traits, std::polymorphic_allocator<CharT>>; } | (2) | (C++17 起)

类模板 `basic_string` 存储并操纵作为非数组平凡标准布局类型的仿 char 对象序列。该类既不依赖字符类型，亦不依赖该类型上的原生操作。操作的定义通过 `Traits` 模板形参—— std::char_traits 的特化或兼容特性类提供。 `Traits::char_type` 和 `CharT` 必须指名同一类型；否则程序非良构。

`basic_string` 是相继存储的，即对于 `basic_string` `s` ，对任何 `[0, s.size())` 中的 n 有 &*(s.begin() + n) == &*s.begin() + n ，或等价地，指向 `s[0]` 的指针能传递给期待指向空终止 (C++11 起) `CharT[]` 数组首元素指针的函数。

`std::basic_string` 满足知分配器容器 (AllocatorAwareContainer) （除了不用定制的 `construct`/`destroy` 构造/析构元素）、序列容器 (SequenceContainer) 及连续容器 (ContiguousContainer) (C++17 起)的要求。

`std::basic_string` 的成员函数为 constexpr ：可以在常量表达式的求值中创建并使用 `std::string` 对象。 然而， `std::string` 对象通常不能为 constexpr ，因为任何动态分配的存储都必须在同一常量表达式求值内释放。 | (C++20 起)

提供数个对于常用字符类型的 typedef ：

定义于头文件 `<string>`
类型 | 定义
std::string | std::basic_string<char>
std::wstring | std::basic_string<wchar_t>
std::u8string (C++20) | std::basic_string<char8_t>
std::u16string (C++11) | std::basic_string<char16_t>
std::u32string (C++11) | std::basic_string<char32_t>
std::pmr::string (C++17) | std::pmr::basic_string<char>
std::pmr::wstring (C++17) | std::pmr::basic_string<wchar_t>
std::pmr::u8string (C++20) | std::pmr::basic_string<char8_t>
std::pmr::u16string (C++17) | std::pmr::basic_string<char16_t>
std::pmr::u32string (C++17) | std::pmr::basic_string<char32_t>

### 模板形参

CharT | - | 字符类型
Traits | - | 指定字符类型上操作的特性类
Allocator | - | 用于分配内部存储的分配器 (Allocator) 类型

### 成员类型

成员类型 | 定义
`traits_type` | `Traits`
`value_type` | `CharT`
`allocator_type` | `Allocator`
`size_type` |
`Allocator::size_type` | (C++11 前)
std::allocator_traits<Allocator>::size_type | (C++11 起)
`difference_type` |
`Allocator::difference_type` | (C++11 前)
std::allocator_traits<Allocator>::difference_type | (C++11 起)
`reference` | value_type&
`const_reference` | const value_type&
`pointer` |
`Allocator::pointer` | (C++11 前)
std::allocator_traits<Allocator>::pointer | (C++11 起)
`const_pointer` |
`Allocator::const_pointer` | (C++11 前)
std::allocator_traits<Allocator>::const_pointer | (C++11 起)
`iterator` |
指向 `value_type` 的老式随机访问迭代器 (LegacyRandomAccessIterator) 及老式连续迭代器 (LegacyContiguousIterator) | (C++20 前)
指向 `value_type` 的老式随机访问迭代器 (LegacyRandomAccessIterator) 、`contiguous_iterator` 及常量表达式迭代器 (ConstexprIterator) | (C++20 起)
`const_iterator` |
指向 `const value_type` 的老式随机访问迭代器 (LegacyRandomAccessIterator) 及老式连续迭代器 (LegacyContiguousIterator) | (C++20 前)
指向 `const value_type` 的老式随机访问迭代器 (LegacyRandomAccessIterator) 、`contiguous_iterator` 及常量表达式迭代器 (ConstexprIterator) | (C++20 起)
`reverse_iterator` | std::reverse_iterator<iterator>
`const_reverse_iterator` | std::reverse_iterator<const_iterator>

### 成员函数

(构造函数) | 构造 `basic_string` (公开成员函数)
(析构函数) | 销毁字符串，若使用内部存储则解分配它 (公开成员函数)
operator= | 为字符串赋值 (公开成员函数)
assign | 赋值字符给字符串 (公开成员函数)
get_allocator | 返回关联的分配器 (公开成员函数)
##### 元素访问
at | 访问指定字符，有边界检查 (公开成员函数)
operator[] | 访问指定字符 (公开成员函数)
front (C++11) | 访问首字符 (公开成员函数)
back (C++11) | 访问最后的字符 (公开成员函数)
data | 返回指向字符串首字符的指针 (公开成员函数)
c_str | 返回字符串的不可修改的 C 字符数组版本 (公开成员函数)
operator basic_string_view (C++17) | 返回到整个字符串的不可修改的 `basic_string_view` (公开成员函数)
##### 迭代器
begin cbegin (C++11) | 返回指向起始的迭代器 (公开成员函数)
end cend (C++11) | 返回指向末尾的迭代器 (公开成员函数)
rbegin crbegin (C++11) | 返回指向起始的逆向迭代器 (公开成员函数)
rend crend (C++11) | 返回指向末尾的逆向迭代器 (公开成员函数)
##### 容量
empty | 检查字符串是否为空 (公开成员函数)
size length | 返回字符数 (公开成员函数)
max_size | 返回字符数的最大值 (公开成员函数)
reserve | 保留存储 (公开成员函数)
capacity | 返回当前对象分配的存储空间能保存的字符数量 (公开成员函数)
shrink_to_fit (C++11) | 通过释放不使用内存减少内存使用 (公开成员函数)
##### 操作
clear | 清除内容 (公开成员函数)
insert | 插入字符 (公开成员函数)
erase | 移除字符 (公开成员函数)
push_back | 后附字符到结尾 (公开成员函数)
pop_back (C++11) | 移除末尾字符 (公开成员函数)
append | 后附字符到结尾 (公开成员函数)
operator+= | 后附字符到结尾 (公开成员函数)
compare | 比较二个字符串 (公开成员函数)
starts_with (C++20) | 检查 string 是否始于给定前缀 (公开成员函数)
ends_with (C++20) | 检查 string 是否终于给定后缀 (公开成员函数)
contains (C++23) | 检查字符串是否含有给定的子串或字符 (公开成员函数)
replace | 替换字符串的指定部分 (公开成员函数)
substr | 返回子串 (公开成员函数)
copy | 复制字符 (公开成员函数)
resize | 更改存储的字符数 (公开成员函数)
resize_and_overwrite (C++23) | 更改存储的字符数并可能经由用户提供的操作重写不确定的内容 (公开成员函数)
swap | 交换内容 (公开成员函数)
##### 查找
find | 于字符串中寻找字符 (公开成员函数)
rfind | 寻找子串的最后一次出现 (公开成员函数)
find_first_of | 寻找字符的首次出现 (公开成员函数)
find_first_not_of | 寻找字符的首次缺失 (公开成员函数)
find_last_of | 寻找字符的最后一次出现 (公开成员函数)
find_last_not_of | 寻找字符的最后一次缺失 (公开成员函数)
### 常量
npos [静态] | 特殊值。准确含义依赖语境 (公开静态成员常量)

### 非成员函数

operator+ | 连接两个字符串或者一个字符串和一个字符 (函数模板)
operator==operator!=operator<operator>operator<=operator>=operator<=> (C++20 中移除)(C++20 中移除)(C++20 中移除)(C++20 中移除)(C++20 中移除)(C++20) | 以字典序比较两个字符串 (函数模板)
std::swap(std::basic_string) | 特化 std::swap 算法 (函数模板)
erase(std::basic_string)erase_if(std::basic_string) (C++20) | 擦除所有满足特定判别标准的元素 (函数模板)
##### 输入/输出
operator<<operator>> | 执行字符串的流输入与输出 (函数模板)
getline | 从 I/O 流读取数据到字符串 (函数模板)
##### 数值转换
stoi stol stoll (C++11)(C++11)(C++11) | 转换字符串为有符号整数 (函数)
stoul stoull (C++11)(C++11) | 转换字符串为无符号整数 (函数)
stof stod stold (C++11)(C++11)(C++11) | 转换字符串为浮点值 (函数)
to_string (C++11) | 转换整数或浮点值为 `string` (函数)
to_wstring (C++11) | 转换整数或浮点值为 `wstring` (函数)

### 字面量

定义于内联命名空间 `std::literals::string_literals`
operator""s (C++14) | 转换字符数组字面量为 `basic_string` (函数)

### 辅助类

std::hash<std::string>std::hash<std::u8string>std::hash<std::u16string>std::hash<std::u32string>std::hash<std::wstring>std::hash<std::pmr::string>std::hash<std::pmr::u8string>std::hash<std::pmr::u16string>std::hash<std::pmr::u32string>std::hash<std::pmr::wstring> (C++11)(C++20)(C++11)(C++11)(C++11)(C++17)(C++20)(C++17)(C++17)(C++17) | string 的散列支持 (类模板特化)

### 推导指引(C++17 起)

### 注解

尽管在 C++23 前要求在构造或销毁 `std::basic_string` 的元素时使用定制的 `construct` 或 `destroy`，所有实现都使用默认机制。P1072R10 更正了该要求以匹配既存实现。

### 示例

    #include <iostream>
    #include <string>

    int main()
    {
        using namespace std::literals;

        // 从 const char* 创建 string
        std::string str1 = "hello";

        // 从字符串字面量创建 string
        auto str2 = "world"s;

        // 连接 string
        std::string str3 = str1 + " " + str2;

        // 打印结果
        std::cout << str3 << '\n';

        std::string::size_type pos = str3.find(" ");
        str1 = str3.substr(pos + 1); // the part after the space
        str2 = str3.substr(0, pos);  // the part till the space

        std::cout << str1 << ' ' << str2 << '\n';

        // 用下标运算符 operator[] 访问元素
        std::cout << str1[0] << '\n';
        str1[0] = 'W';
        std::cout << str1 << '\n';
    }

输出：

    hello world
    world hello
    w
    World