В этом подразделе определяются требования по классам , представляющих
character traitsи определяет шаблон класса
char_traits<charT>, наряду с четырьмя специализациями,
char_traits<char>,
char_traits<char16_t>,
char_traits<char32_t>, и
char_traits<wchar_t>, которые удовлетворяют этим требованиям.
Большинство классов , указанных в пунктах[string.classes] и[input.output] нужен набор связанных типов и функций , чтобы завершить определение их семантики. Эти типы и функции предоставляются как набор членов typedef-names и функций в параметре шаблона,traits используемом каждым таким шаблоном. В этом подпункте определяется семантика этих членов.
Чтобы специализировать эти шаблоны для создания строки или класса iostream для обработки определенного типа контейнера символов CharT, этот и связанный с ним класс характеристик символов Traits передаются в виде пары параметров в строку или шаблон iostream как параметры charT и traits. Traits::char_type должно быть таким же, как CharT.
Этот подраздел определяет шаблон класса, char_traits<charT>и четыре явных специализаций этого, char_traits<char>, char_traits<char16_t>, char_traits<char32_t>, и char_traits<wchar_t>, все из которых появляются в заголовке <string> и удовлетворяют требования ниже.
В таблице54, X обозначает класс черты , определяющий типы и функции для символьного типа контейнера CharT; c и d обозначают значения типа CharT; p и q обозначают значения типа const CharT*; s обозначает значение типа CharT*; n, i и j обозначают значения типа size_t; e и f обозначают значения типа X::int_type; pos обозначает значение типа X::pos_type; state обозначает значение типа X::state_type; и r обозначает lvalue типа CharT. Операции с Чертами не должны вызывать исключений.
Выражение | Тип возврата | Утверждение / примечание | Сложность |
до / после состояния | |||
X::char_type | charT | (описано в[char.traits.typedefs]) | время компиляции |
X::int_type | (описано в[char.traits.typedefs]) | время компиляции | |
X::off_type | (описано в[char.traits.typedefs]) | время компиляции | |
X::pos_type | (описано в[char.traits.typedefs]) | время компиляции | |
X::state_type | (описано в[char.traits.typedefs]) | время компиляции | |
X::eq(c,d) | bool | Returns: следует лиc рассматривать как равноеd. | постоянный |
X::lt(c,d) | bool | Returns: следует лиc рассматривать как меньшее, чемd. | постоянный |
X::compare(p,q,n) | int | Returns:0 если для каждогоi в[0,n),X::eq(p[i],q[i]) естьtrue; иначе, отрицательное значение , если для некоторыхj ин[0,n), X::lt(p[j],q[j]) этоtrue и для каждогоi дюйма[0,j) X::eq(p[i],q[i]) являетсяtrue; иначе положительное значение. | линейный |
X::length(p) | size_t | Returns: самый маленькийi такой чтоX::eq(p[i],charT()) естьtrue. | линейный |
X::find(p,n,c) | const X::char_type* | Returns: наименьшееq в[p,p+n) таком, то X::eq(*q,c) естьtrue, в противном случае ноль. | линейный |
X::move(s,p,n) | X::char_type* |
для каждогоi в[0,n), выполняетX::assign(s[i],p[i]). Копирует правильно даже там, где диапазоны[p,p+n) и[s,s+n) перекрываются. Returns:s. | линейный |
X::copy(s,p,n) | X::char_type* |
Requires:p не в[s,s+n).Returns:s. для каждогоi в [0,n), выполняетX::assign(s[i],p[i]). | линейный |
X::assign(r,d) | (не используется) | назначаетr=d. | постоянный |
X::assign(s,n,c) | X::char_type* |
для каждогоi в[0,n), выполняет
X::assign(s[i],c). Returns:s. | линейный |
X::not_eof(e) | int_type | Returns:e еслиX::eq_int_type(e,X::eof()) естьfalse, в противном случае такое значениеf , которое X::eq_int_type(f,X::eof()) естьfalse. | постоянный |
X::to_char_type(e) | X::char_type | Returns: если для некоторыхc,X::eq_int_type(e,X::to_int_type(c)) этоtrue,c; иначе какое-то неопределенное значение. | постоянный |
X::to_int_type(c) | X::int_type | Returns: некоторая ценностьe, ограниченная определениями to_char_type иeq_int_type. | постоянный |
X::eq_int_type(e,f) | bool | Returns: для всехc иd,X::eq(c,d) равно X::eq_int_type(X::to_int_type(c), X::to_int_type(d)); в противном случае выдаетtrue ife иf обе копииX::eof(); в противном случае уступает,false если одно изe иf является копией,X::eof() а другое - нет; в противном случае значение не указано. | постоянный |
X::eof() | X::int_type | Returns: такое значениеe , котороеX::eq_int_type(e,X::to_int_type(c)) естьfalse для всех значенийc. | постоянный |
using char_type = CHAR_T;
Тип char_type используется для ссылки на тип символьного контейнера в реализации библиотечных классов, определенных в[string.classes] разделе и[input.output].
using int_type = INT_T;
Requires: Для определенного типа характера контейнера char_type, связанный тип контейнера INT_T должен быть типа или класса , который может представлять все допустимые символы , преобразованных из соответствующих char_type значений, а также значение конца-файла eof(). Типint_type представляет собой тип символьного контейнера, который может содержать конец файла, который будет использоваться в качестве возвращаемого типа функций-членов класса iostream.224
using off_type = implementation-defined;
using pos_type = implementation-defined;
Requires: Требования к off_type и pos_type описаны в[iostreams.limits.pos] и[iostream.forward].
using state_type = STATE_T;
Requires: state_type должны отвечать требованиям CopyAssignable, CopyConstructibleи DefaultConstructible типов.
Если их eof() можно char_type удержать, то некоторые операции iostreams могут дать удивительные результаты.
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>; }
Заголовок <string> определяет четыре специализации шаблона класса char_traits: char_traits<char>, char_traits<char16_t>, char_traits<char32_t>, и char_traits<wchar_t>.
namespace std { template<> struct char_traits<char> { using char_type = char; using int_type = int; using off_type = streamoff; using pos_type = streampos; 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; }; }
Определенные типы для int_type, pos_type, off_typeи state_type должно быть int, streampos, streamoffи mbstate_t соответственно.
Типstreampos должен быть типом , определяемым реализацией, который удовлетворяет требованиям pos_type в[iostreams.limits.pos] и[iostream.forward].
Типstreamoff должен быть типом , определяемым реализацией, который удовлетворяет требованиям off_type в[iostreams.limits.pos] и[iostream.forward].
Тип mbstate_t определяется <cwchar> и может представлять любое из состояний преобразования, которое может происходить в определяемом реализацией наборе поддерживаемых правил кодирования многобайтовых символов.
Член с двумя аргументамиassign должен быть определен идентично встроенному оператору=. Члены с двумя аргументамиeq иlt должны быть определены идентично встроенным операторам == и< типуunsigned char.
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; }; }
Типu16streampos должен быть типом , определяемым реализацией, который удовлетворяет требованиямpos_type в[iostreams.limits.pos] и[iostream.forward].
Члены двух аргументовassign, eqиlt должны быть определены тождественны встроенными операторами=,==и < соответственно.
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; }; }
Типu32streampos должен быть типом , определяемым реализацией, который удовлетворяет требованиямpos_type в[iostreams.limits.pos] и[iostream.forward].
Члены двух аргументовassign, eqиlt должны быть определены тождественны встроенными операторами=,==и < соответственно.
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; }; }
Определенные типы для int_type, pos_typeи state_type должны быть wint_t, wstreamposи mbstate_t соответственно.
Типwstreampos должен быть типом , определяемым реализацией, который удовлетворяет требованиямpos_type в[iostreams.limits.pos] и[iostream.forward].
Тип mbstate_t определяется <cwchar> и может представлять любое из состояний преобразования, которое может происходить в определяемом реализацией наборе поддерживаемых правил кодирования многобайтовых символов.
Члены двух аргументов assign, eqи lt должны быть определены тождественны встроенными операторами =, ==и < соответственно.