21.1 General

1.此节描述了控制任何非数组POD类型序列的组件。在本节这样的类型被称为char-like type,char-like type的对象被称为char-like object或简略地称为characters。

2.下列子小节描述character traits class,string class和null-terminated sequence utilities。

21.2 Character traits

1.此小节定义表示character traits类的要求,并且定义类模板char_traits<CharT>,以及它的4种特化,char_traits<char>,char_traits<char16_t>,char_traits<char32_t>,char_traits<wchar_t>,它们满足这些要求。

2.大多数在条款21.3和27中描述的类需要相关类型集合和实现它们语义解释的函数。这些类型和函数在每个模板中使用的模板参数traits中作为成员类型和成员函数集合提供。此小节定义这些成员保证的语义。

3.要专门设置这些模板以生成string或iostream类来处理特定字符容器类型CharT,该类及其相关的character traits类Traits作为一对参数传递给string或iostream模板,作为形式参数charT和traits。Traits::char_type和CharT相同。

4.此小节详述结构体模板,char_traits<charT>,以及它的4个显式特化,char_traits<char>,char_traits<char16_t>,char_traits<char32_t>,char_traits<wchar_t>,这些均出现在头文件<string>中并且满足下面的要求。

21.2.1 Character traits requirements

1.Table 62中,X表示Traits类,用于定义字符容器类型CharT的类型和函数;c和d表示类型CharT的值;p和q表示类型const CharT的值;s表示类型CharT的值;i和j表示类型std::size_t的值;e和f表示类型X::int_type的值;pos表示类型X::pos_type的值;state表示类型X::state_type的值;r表示类型CharT的左值。Traits上的运算符禁止抛出异常。

Table 62.

2.结构体模板template<class charT> struct char_traits;应在<string>中作为显式特化的基础被提供。

21.2.2 traits typedefs

typedef CHAR_T char_type;

1.类型char_type用于引用21.3和27中定义的库的视线中的字符容器类型。

typedef INT_T int_type;

2.要求: 对于某个字符容器类型char_type,相关的容器类型INT_T应是一个类型或类,它可以表示从相应的char_type值转换的所有有效字符,以及文件尾值eof()。类型int_type表示一个字符容器类型,该类型可以保存文件结束以用作iostream类成员函数的返回类型。

typedef implementation-defined off_type;

typedef implementation-defined pos_type;

3.要求: 27.2.2和27.3中off_type和pos_type的要求。

typedef STATE_T state_type;

4.要求: state_type应满足CopyAssignable,CopyConstructible和DefaultConstructilbe类型的要求。

21.2.3 char_traits specializations

namespace std { 
  template<> struct char_traits<char>; 
  template<> struct char_traits<char16_t>; 
  template<> struct char_traits<char32_t>; 
  template<> struct char_traits<wchar_t>; 
}

1.头文件<string>应定义char_traits的4种特化:char_traits<char>,char_traits<char16_t>,char_traits<char32_t>,char_traits<wchar_t>

2.这些特化的成员所需要求在21.2.1中给出。

21.2.3.1 struct char_traits<char>
namespace std { 
  template<> struct char_traits<char> { 
    typedef char char_type; 
    typedef int int_type; 
    typedef streamoff off_type; 
    typedef streampos pos_type; 
    typedef mbstate_t state_type;

    static void assign(char_type& c1, const char_type& c2) noexcept; 
    static constexpr bool eq(char_type c1, char_type c2) noexcept; 
    static constexpr bool lt(char_type c1, char_type c2) noexcept;

    static int compare(const char_type* s1, const char_type* s2, size_t n); 
    static size_t length(const char_type* s); 
    static const char_type* find(const char_type* s, size_t n, const char_type& a); 
    static char_type* move(char_type* s1, const char_type* s2, size_t n); 
    static char_type* copy(char_type* s1, const char_type* s2, size_t n); 
    static char_type* assign(char_type* s, size_t n, char_type a);

    static constexpr int_type not_eof(int_type c) noexcept; 
    static constexpr char_type to_char_type(int_type c) noexcept; 
    static constexpr int_type to_int_type(char_type c) noexcept; 
    static constexpr bool eq_int_type(int_type c1, int_type c2) noexcept; 
    static constexpr int_type eof() noexcept;
  };
} 

1.int_type,pos_type,off_type,state_type定义的类型应分别是int,streampos,streamoff,mbstate_t。

2.类型streampos应是满足pos_type要求的实现定义的类型。

3.类型streamoff应是满足off_type要求的实现定义的类型。

4.类型mbstate_t定义在<cwchar>且可以表示在实现定义的一组受支持的多字节字符编码规则中可能发生的任何转换状态。

5.assign的2个参数应与内置运算符=相同。对类型unsigned char来说,eq和lt的2个参数应与内置运算符==和<相同。

6.成员函数 eof() 应返回EOF。

24.2.3.2 struct char_traits<char16_t>
namespace std { 
  template<> struct char_traits<char16_t> { 
    using char_type = char16_t; 
    using int_type = uint_least16_t; 
    using off_type = streamoff; 
    using pos_type = u16streampos; 
    using state_type = mbstate_t;

    static constexpr void assign(char_type& c1, const char_type& c2) noexcept; 
    static constexpr bool eq(char_type c1, char_type c2) noexcept; 
    static constexpr bool lt(char_type c1, char_type c2) noexcept;

    static constexpr int compare(const char_type* s1, const char_type* s2, size_t n); 
    static constexpr size_t length(const char_type* s); 
    static constexpr const char_type* find(const char_type* s, size_t n, const char_type& a); 
    static char_type* move(char_type* s1, const char_type* s2, size_t n); 
    static char_type* copy(char_type* s1, const char_type* s2, size_t n); 
    static char_type* assign(char_type* s, size_t n, char_type a);
    static constexpr int_type not_eof(int_type c) noexcept; 
    static constexpr char_type to_char_type(int_type c) noexcept; 
    static constexpr int_type to_int_type(char_type c) noexcept; 
    static constexpr bool eq_int_type(int_type c1, int_type c2) noexcept; 
    static constexpr int_type eof() noexcept;
  };
}

1.类型u16streampos应是满足pos_type要求的由实现定义的类型。

2.有两个参数的成员assign,eqlt必须分别与内置运算符=,==和<相同地定义。

3.成员eof()应返回不能再合理的UTF-16编码单元中展示的由实现定义的常量。

24.2.3.3 struct char_traits<char32_t>
namespace std { 
  template<> struct char_traits<char32_t> { 
    using char_type = char32_t; 
    using int_type = uint_least32_t; 
    using off_type = streamoff; 
    using pos_type = u32streampos; 
    using state_type = mbstate_t;

    static constexpr void assign(char_type& c1, const char_type& c2) noexcept; 
    static constexpr bool eq(char_type c1, char_type c2) noexcept; 
    static constexpr bool lt(char_type c1, char_type c2) noexcept;

    static constexpr int compare(const char_type* s1, const char_type* s2, size_t n); 
    static constexpr size_t length(const char_type* s); 
    static constexpr const char_type* find(const char_type* s, size_t n, const char_type& a); 
    static char_type* move(char_type* s1, const char_type* s2, size_t n); 
    static char_type* copy(char_type* s1, const char_type* s2, size_t n); 
    static char_type* assign(char_type* s, size_t n, char_type a);

    static constexpr int_type not_eof(int_type c) noexcept; 
    static constexpr char_type to_char_type(int_type c) noexcept; 
    static constexpr int_type to_int_type(char_type c) noexcept; 
    static constexpr bool eq_int_type(int_type c1, int_type c2) noexcept; 
    static constexpr int_type eof() noexcept;
  };
} 

1.类型u16streampos应是满足pos_type要求的由实现定义的类型。

2.有两个参数的成员assign,eqlt必须分别与内置运算符=,==和<相同地定义。

3.成员eof()应返回不能再合理的UTF-16编码单元中展示的由实现定义的常量。

24.2.3.4 struct char_traits<wchar_t>
namespace std { 
  template<> struct char_traits<wchar_t> { 
    using char_type = wchar_t; 
    using int_type = wint_t; 
    using off_type = streamoff; 
    using pos_type = wstreampos; 
    using state_type = mbstate_t;

    static constexpr void assign(char_type& c1, const char_type& c2) noexcept; 
    static constexpr bool eq(char_type c1, char_type c2) noexcept; 
    static constexpr bool lt(char_type c1, char_type c2) noexcept;

    static constexpr int compare(const char_type* s1, const char_type* s2, size_t n); 
    static constexpr size_t length(const char_type* s); 
    static constexpr const char_type* find(const char_type* s, size_t n, const char_type& a); 
    static char_type* move(char_type* s1, const char_type* s2, size_t n); 
    static char_type* copy(char_type* s1, const char_type* s2, size_t n); 
    static char_type* assign(char_type* s, size_t n, char_type a);

    static constexpr int_type not_eof(int_type c) noexcept; 
    static constexpr char_type to_char_type(int_type c) noexcept; 
    static constexpr int_type to_int_type(char_type c) noexcept; 
    static constexpr bool eq_int_type(int_type c1, int_type c2) noexcept; 
    static constexpr int_type eof() noexcept;
  };
}

1.定义的类型int_type,pos_type和state_type应分别是wint_t,wstreampos,和mbstate_t。

2.wstreampos应是满足pos_type要求的由实现定义的类型。

3.类型mbstate_t定义在<cwchar>且可以表示在实现定义的一组受支持的多字节字符编码规则中可能发生的任何转换状态。

4.有两个参数的成员assign,eqlt必须分别与内置运算符=,==和<相同地定义。

5.成员eof()应返回不能再合理的UTF-16编码单元中展示的由实现定义的常量。

24.3 String classes

1.头文件<string>定义用于操作char-like变长序列对象的basic_string类模板 和4种类型定义名字,string,u16string,u32string和wstring,这4种分别是特化,basic_string<char>,basic_string<char16_t>,basic_string<char32_t>和basic_string<wchar_t>

24.3.1 Header <string> synopsis

p673

24.3.2 Class template basic_string

1.类模板basic_string描述可以存储序列的对象,该序列由不同数量的任意char型对象组成,序列的第一个元素位于index 0。如果从上下文可以清楚地知道所持有的char型对象类型,则此序列也被称为“string”。此条款的其余部分,basic_string对象中的char型对象类型由charT指定。

2.basic_string的成员函数使用通过模板参数传递的Allocator的一个对象来申请和释放所包含的char型对象的空间。

3.一个basic_string是连续容器。

4.所有例子中,size() <= capacity()。

5.此条款描述的函数可以上报二种error,每个都和exception类型有关:

24.3.2.1 basic_string general requirements

1.如果某个操作会导致size()超过max_size(),该操作应抛出length_error异常对象。

2.如果basic_string某个成员函数或操作抛出异常,该函数或操作应没有其他作用。

3.每个basic_string<charT,traits,Allocator>特化中,类型allocator_traits<Allocator>::value_type应命名与charT相同的类型。每个basic_string<charT,traits,Allocator>类型的对象应根据需要使用Allocator对象来申请和释放包含的charT对象的空间。使用的Allocator对象应如26.2.1所述获得。每个basic_string<charT,traits,Allocator>特化中,类型traits应满足character traits要求(24.2),并且类型traits::char_type应命名与charT相同的类型。

4.在下列basic_string对象使用中,basic_string序列元素的引用,指针和迭代器引用可能不合法:

basic_string constructors and assignment operators

explicit basic_string(const Allocator& a) noexcept;

1.作用: 构造basic_string对象。此函数的后置条件在table55中指出。

basic_string(const basic_string& str);

basic_string(basic_string&& str) noexcept;

2.作用: 构造table56中指出的basic_string对象。第二个形式中,str处于有效状态,具有未指定的值。

basic_string(const basic_string& str, size_type pos, const Allocator& a = Allocator());

basic_string(const basic_string& str, size_type pos, size_type n, const Allocator& a = Allocator());

3.Throw: 如果pos > str.size(),out_of_range。

4.作用: 构造basic_string对象。在第一形式中,确定初始string值有效长度rlen为str.size() - pos;在第二形式中,确定初始string值有效长度rlen为str.size() - pos和n的较小值;table57中指出。

template<class T> basic_string(const T& t, size_type pos,

size_type n, const Allocator& a = Allocator());

5.作用: 创建一个变量,sv,就像basic_string_view<charT,traits> sv=t;其行为和basic_string(sv.substr(pos,n), a);一样。

6.备注: 此构造函数禁止参与重载决议,除非is_convertible_v<const T&, basic_string_view<charT, traits>>是true。

explicit basic_string(basic_string_view<charT, traits> sv, const Allocator& a = Allocator());

7.作用: 与basic_string(sv.data(), sv.size(), a)一样。

basic_string(const charT* s, size_type n, const Allocator& a = Allocator());

8.要求: s指向指向charT的最少n个元素的数组。

9.作用: 构造basic_string对象。从首元素由s指定的长度为n的charT数组中指定它的初始string值,在table58中指出。

basic_string(const charT* s, const Allocator& a = Allocator());

10.要求: s指向指向charT的最少traits::length(s)+1个元素的数组。

11.作用: 构造basic_string对象。从首元素由s指定的长度为traits::length(s)的charT数组中指定它的初始string值,在table58中指出。

p682

[Example: -end example]

[Note: -end note]

17 draft