# std::basic_string<CharT,Traits,Allocator>::basic_string

< cpp‎ | string‎ | basic string

| (1) |
basic_string(); explicit basic_string( const Allocator& alloc ); |  | (C++17 前)
basic_string() noexcept(noexcept( Allocator() )) : basic_string( Allocator() ) {} explicit basic_string( const Allocator& alloc ) noexcept; |  | (C++17 起) (C++20 前)
constexpr basic_string() noexcept(noexcept( Allocator() )) : basic_string( Allocator() ) {} explicit constexpr basic_string( const Allocator& alloc ) noexcept; |  | (C++20 起)
| (2) |
basic_string( size_type count, CharT ch, const Allocator& alloc = Allocator() ); |  | (C++20 前)
constexpr basic_string( size_type count, CharT ch, const Allocator& alloc = Allocator() ); |  | (C++20 起)
| (3) |
basic_string( const basic_string& other, size_type pos, size_type count = std::basic_string::npos, const Allocator& alloc = Allocator() ); |  | (C++17 前)
basic_string( const basic_string& other, size_type pos, const Allocator& alloc = Allocator() ); |  | (C++17 起) (C++20 前)
constexpr basic_string( const basic_string& other, size_type pos, const Allocator& alloc = Allocator() ); |  | (C++20 起)
| (3) |
basic_string( const basic_string& other, size_type pos, size_type count, const Allocator& alloc = Allocator() ); |  | (C++17 起) (C++20 前)
constexpr basic_string( const basic_string& other, size_type pos, size_type count, const Allocator& alloc = Allocator() ); |  | (C++20 起)
| (4) |
basic_string( const CharT* s, size_type count, const Allocator& alloc = Allocator() ); |  | (C++20 前)
constexpr basic_string( const CharT* s, size_type count, const Allocator& alloc = Allocator() ); |  | (C++20 起)
| (5) |
basic_string( const CharT* s, const Allocator& alloc = Allocator() ); |  | (C++20 前)
constexpr basic_string( const CharT* s, const Allocator& alloc = Allocator() ); |  | (C++20 起)
| (6) |
template< class InputIt > basic_string( InputIt first, InputIt last, const Allocator& alloc = Allocator() ); |  | (C++20 前)
template< class InputIt > constexpr basic_string( InputIt first, InputIt last, const Allocator& alloc = Allocator() ); |  | (C++20 起)
| (7) |
basic_string( const basic_string& other ); |  | (C++20 前)
constexpr basic_string( const basic_string& other ); |  | (C++20 起)
| (7) |
basic_string( const basic_string& other, const Allocator& alloc ); |  | (C++11 起) (C++20 前)
constexpr basic_string( const basic_string& other, const Allocator& alloc ); |  | (C++20 起)
| (8) |
basic_string( basic_string&& other ) noexcept; |  | (C++11 起) (C++20 前)
constexpr basic_string( basic_string&& other ) noexcept; |  | (C++20 起)
| (8) |
basic_string( basic_string&& other, const Allocator& alloc ); |  | (C++11 起) (C++20 前)
constexpr basic_string( basic_string&& other, const Allocator& alloc ); |  | (C++20 起)
| (9) |
basic_string( std::initializer_list<CharT> ilist, const Allocator& alloc = Allocator() ); |  | (C++11 起) (C++20 前)
constexpr basic_string( std::initializer_list<CharT> ilist, const Allocator& alloc = Allocator() ); |  | (C++20 起)
| (10) |
template < class T > explicit basic_string( const T& t, const Allocator& alloc = Allocator() ); |  | (C++17 起) (C++20 前)
template < class T > explicit constexpr basic_string( const T& t, const Allocator& alloc = Allocator() ); |  | (C++20 起)
| (11) |
template < class T > basic_string( const T& t, size_type pos, size_type n, const Allocator& alloc = Allocator() ); |  | (C++17 起) (C++20 前)
template < class T > constexpr basic_string( const T& t, size_type pos, size_type n, const Allocator& alloc = Allocator() ); |  | (C++20 起)
constexpr basic_string( std::nullptr_t ) = delete; | (12) | (C++23 起)

从各种数据源构造新 string ，可选地使用用户提供的分配器 `alloc` 。

1) 默认构造函数。构造空 string （拥有零大小和未指定的容量）。若不提供分配器，则从默认构造的实例获得分配器。
2) 构造拥有字符 `ch` 的 `count` 个副本的 string 。若会推导出不足以作为分配器的 `Allocator` 类型，则此构造函数不用于类模板实参推导。 (C++17 起)
3) 以 `other` 的子串 `[pos, pos+count)` 构造 string 。若 count == npos 或未指定 `count` ，或若请求的子串越过字符串的结尾，则产生的子串为 `[pos, other.size())` 。
4) 以 `s` 所指向的字符串的首 `count` 个字符构造 string 。 `s` 能包含空字符。 string 的长度为 `count` 。若 `[s, s + count)` 不是合法范围则行为未定义。
5) 以 `s` 所指向的空终止字符串的副本所初始化的内容构造 string 。以首个空字符确定字符串的长度。若 `[s, s + Traits::length(s))` 不是合法范围（例如若 `s` 是空指针）则行为未定义。若会推导出不足以作为分配器的 `Allocator` 类型，则此构造函数不用于类模板实参推导。 (C++17 起)
6) 构造拥有范围 `[first, last)` 内容的 string 。

若 `InputIt` 为整数类型，则等价于 `basic_string(static_cast<size_type>(first), static_cast<value_type>(last), a)` 。 | (C++11 前)
此构造函数仅若 `InputIt` 满足 老式输入迭代器 (LegacyInputIterator) 才参与重载决议。 | (C++11 起)

7) 复制构造函数。构造拥有 `other` 内容副本的 string 。
8) 移动构造函数。用移动语义构造拥有 `other` 内容的 string 。将 `other` 留在合法但未指定的状态。
9) 构造拥有 initializer_list `ilist` 内容的 string 。
10) 如同用 std::basic_string_view<CharT, Traits> sv = t; 隐式转换 `t` 为 string_view `sv` ，然后如同用 basic_string(sv.data(), sv.size(), alloc) ，以 `sv` 的内容初始化 string 。此重载仅若 std::is_convertible_v<const T&, std::basic_string_view<CharT, Traits>> 为 true 且 std::is_convertible_v<const T&, const CharT*> 为 false 才参与重载决议。
11) 如同用 std::basic_string_view<CharT, Traits> sv = t; 隐式转换 `t` 为 string_view `sv` ，然后如同用 basic_string(sv.substr(pos, n), a) ，以 `sv` 的子范围 `[pos, pos + n)` 初始化 string 。此重载仅若 std::is_convertible_v<const T&, std::basic_string_view<CharT, Traits>> 为 true 才参与重载决议。
12) 不能从 nullptr 构造 `basic_string` 。

### 参数

alloc | - | 用于此 string 所有内存分配的分配器
count | - | 产生的 string 大小
ch | - | 初始化 string 所用的值
pos | - | 要包含的首字符位置
first, last | - | 复制字符的来源范围
s | - | 指向用作源初始化 string 的字符数组的指针
other | - | 用作源初始化 string 的另一 string
ilist | - | 初始化 string 所用的 std::initializer_list
t | - | 初始化 string 所用的对象（可转换为 std::basic_string_view ）

### 复杂度

1) 常数
2-4) 与 `count` 成线性
5) 与 `s` 的长度成线性
6) 与 `first` 和 `last` 间的距离成线性
7) 与 `other` 的大小成线性
8) 常数。若给出 `alloc` 且 alloc != other.get_allocator() 则为线性
9) 与 `ilist` 的大小成线性

### 异常

3) 若 pos > other.size() 则为 std::out_of_range
8) 若 alloc == str.get_allocator() 则不抛出
11) 若 pos 在范围外则为 std::out_of_range

若构造的字符串长度会超出 max_size() （例如对于 (2) ，若 count > max_size() ）则抛出 std::length_error 。调用 `Allocator::allocate` 可能抛出。

### 注意

以含内嵌 '\0' 字符的字符串字面量初始化 string 会使用重载 (5) ，并在首个空字符停止。这可通过指定不同的构造函数，或通过使用 `operator""s` 避免：

    std::string s1 = "ab\0\0cd";   // s1 含 "ab"
    std::string s2{"ab\0\0cd", 6}; // s2 含 "ab\0\0cd"
    std::string s3 = "ab\0\0cd"s;  // s3 含 "ab\0\0cd"

### 缺陷报告

下列更改行为的缺陷报告追溯地应用于以前出版的 C++ 标准。

DR | 应用于 | 出版时的行为 | 正确行为
--- | --- | --- | ---
LWG 2193 | C++11 | 默认构造函数为 explicit | 使之为非 explicit
LWG 2946 | C++17 | `string_view` 重载在一些情况下导致歧义 | 通过使之为模板来避免
LWG 3076 | C++17 | 二个构造函数可能在类模板实参推导中导致歧义 | 已制约

### 示例

    #include <iostream>
    #include <cassert>
    #include <iterator>
    #include <string>
    #include <cctype>

    int main()
    {
      {
        // string::string()
        std::string s;
        assert(s.empty() && (s.length() == 0) && (s.size() == 0));
      }

      {
        // string::string(size_type count, charT ch)
        std::string s(4, '=');
        std::cout << s << '\n'; // "===="
      }

      {
        std::string const other("Exemplary");
        // string::string(string const& other, size_type pos, size_type count)
        std::string s(other, 0, other.length()-1);
        std::cout << s << '\n'; // "Exemplar"
      }

      {
        // string::string(charT const* s, size_type count)
        std::string s("C-style string", 7);
        std::cout << s << '\n'; // "C-style"
      }

      {
        // string::string(charT const* s)
        std::string s("C-style\0string");
        std::cout << s << '\n'; // "C-style"
      }

      {
        char mutable_c_str[] = "another C-style string";
        // string::string(InputIt first, InputIt last)
        std::string s(std::begin(mutable_c_str)+8, std::end(mutable_c_str)-1);
        std::cout << s << '\n'; // "C-style string"
      }

      {
        std::string const other("Exemplar");
        std::string s(other);
        std::cout << s << '\n'; // "Exemplar"
      }

      {
        // string::string(string&& str)
        std::string s(std::string("C++ by ") + std::string("example"));
        std::cout << s << '\n'; // "C++ by example"
      }

      {
        // string(std::initializer_list<charT> ilist)
        std::string s({ 'C', '-', 's', 't', 'y', 'l', 'e' });
        std::cout << s << '\n'; // "C-style"
      }

      {
        // 重载决议选择 string(InputIt first, InputIt last) [with InputIt = int]
        // 这表现为如同调用 string(size_type count, charT ch)
        std::string s(3, std::toupper('a'));
        std::cout << s << '\n'; // "AAA"
      }
    }

输出：

    ====
    Exemplar
    C-style
    C-style
    C-style string
    Exemplar
    C++ by example
    C-style
    AAA

### 参阅

assign | 赋值字符给字符串 (公开成员函数)
operator= | 为字符串赋值 (公开成员函数)
to_string (C++11) | 转换整数或浮点值为 `string` (函数)
to_wstring (C++11) | 转换整数或浮点值为 `wstring` (函数)