20 Library introduction [library]

20.5 Library-wide requirements [requirements]

В этом подпункте указаны требования, которые применяются ко всей стандартной библиотеке C ++. Пункты [language.support] до [thread] и Приложение [depr] определяют требования отдельных организаций в библиотеке.

Требования, указанные в терминах взаимодействия между потоками, не применяются к программам, имеющим только один поток выполнения.

В этом подпункте [organization] описывается содержимое и организация библиотеки, [using] описывается, как правильно сформированные программы C ++ получают доступ к объектам библиотеки, [utility.requirements] описываются ограничения на типы и функции, используемые со стандартной библиотекой C ++, [constraints] описываются ограничения на правильно сформированные программы на C ++ и [conforming] описываются ограничения на соответствующие реализации.

20.5.1 Library contents and organization [organization]

[contents] описывает сущности и макросы, определенные в стандартной библиотеке C ++. [headers] перечисляет заголовки стандартной библиотеки и некоторые ограничения на эти заголовки. [compliance] перечисляет требования к автономной реализации стандартной библиотеки C ++.

20.5.1.1 Library contents [contents]

Стандартная библиотека C ++ предоставляет определения для сущностей и макросов, описанных в резюме заголовков стандартной библиотеки C ++ ([headers]).

Все объекты библиотеки, кроме operator new и operator delete , определены в пространстве имен std или пространствах имен, вложенных в пространство имен std. Не указано, объявляются ли имена, объявленные в определенном пространстве имен, непосредственно в этом пространстве имен или во встроенном пространстве имен внутри этого пространства имен.166167

Всякий раз, когда x упоминается имя, определенное в стандартной библиотеке, x предполагается , что имя полностью определено как ​::​std​::​x, если явно не указано иное. Например, если Effects: раздел для библиотечной функции F описывается как вызывающая библиотечная функция G,​::​std​::​G имеется в виду функция .

Заголовки стандартной библиотеки C (Приложение [depr.c.headers]) также определяют имена в глобальном пространстве имен, в то время как заголовки C ++ для средств библиотеки C ([headers]) могут также определять имена в глобальном пространстве имен.

Это дает разработчикам свободу использовать встроенные пространства имен для поддержки нескольких конфигураций библиотеки.

20.5.1.2 Headers [headers]

Каждый элемент стандартной библиотеки C ++ объявлен или определен (при необходимости) в файле header.168

Стандартная библиотека C ++ предоставляет C++ library headers, как показано в Табл 16.

Таблица 16 - заголовки библиотеки C ++
<algorithm> <future> <numeric> <strstream>
<any> <initializer_­list> <optional> <system_­error>
<array> <iomanip> <ostream> <thread>
<atomic> <ios> <queue> <tuple>
<bitset> <iosfwd> <random> <type_­traits>
<chrono> <iostream> <ratio> <typeindex>
<codecvt> <istream> <regex> <typeinfo>
<complex> <iterator> <scoped_­allocator> <unordered_­map>
<condition_­variable> <limits> <set> <unordered_­set>
<deque> <list> <shared_­mutex> <utility>
<exception> <locale> <sstream> <valarray>
<execution> <map> <stack> <variant>
<filesystem> <memory> <stdexcept> <vector>
<forward_­list> <memory_­resource> <streambuf>
<fstream> <mutex> <string>
<functional> <new> <string_­view>

Возможности стандартной библиотеки C представлены в дополнительных заголовках, показанных в таблице 17.169

Таблица 17 - Заголовки C ++ для средств библиотеки C
<cassert> <cinttypes> <csignal> <cstdio> <cwchar>
<ccomplex> <ciso646> <cstdalign> <cstdlib> <cwctype>
<cctype> <climits> <cstdarg> <cstring>
<cerrno> <clocale> <cstdbool> <ctgmath>
<cfenv> <cmath> <cstddef> <ctime>
<cfloat> <csetjmp> <cstdint> <cuchar>

За исключением указанных в пунктах [library] через [thread] и приложение [depr], содержание каждого заголовка cname такое же , как и у соответствующего заголовка , name.h как указано в разделе C standard library. Однако в стандартной библиотеке C ++ объявления (за исключением имен, которые определены как макросы в C) находятся в пределах namespace scope пространства имен std. Не указано, были ли эти имена (включая любые перегрузки, добавленные в разделах [language.support] по [thread] и Приложение [depr]) сначала объявлены в области глобального пространства имен, а затем std явно введены в пространство имен using-declarations.

Имена, которые определены как макросы в C, должны определяться как макросы в стандартной библиотеке C ++, даже если C предоставляет лицензию на реализацию в качестве функций. [ Note: Имена , определенные как макросы в C включают в себя следующее: assert, offsetof, setjmp, va_­arg, va_­end, и va_­start. ] end note

Имена, которые определены как функции в C, должны быть определены как функции в стандартной библиотеке C ++.170

Идентификаторы, которые являются ключевыми словами или операторами в C ++, не должны определяться как макросы в заголовках стандартной библиотеки C ++.171

[depr.c.headers], Заголовки стандартной библиотеки C, описывает эффекты использования формы name.h (заголовок C) в программе на C ++.172

Приложение K к стандарту C описывает большое количество функций с соответствующими типами и макросами, которые «способствуют более безопасному и безопасному программированию», чем многие традиционные функции библиотеки C. Имена функций имеют суффикс _­s; большинство из них предоставляют ту же услугу, что и функция библиотеки C с именем без суффиксов, но обычно принимают дополнительный аргумент, значение которого является размером массива результатов. Если включен какой-либо заголовок C ++, это определяется реализацией, объявлено ли какое-либо из этих имен в глобальном пространстве имен. (Ни один из них не объявлен в пространстве имен std.)

В таблице 18 перечислены имена Приложения K, которые могут быть объявлены в каком-либо заголовке. На эти имена также распространяются ограничения [macro.names].

Таблица 18 - Стандартные названия C, приложения K
abort_­handler_­s mbstowcs_­s strncat_­s vswscanf_­s
asctime_­s memcpy_­s strncpy_­s vwprintf_­s
bsearch_­s memmove_­s strtok_­s vwscanf_­s
constraint_­handler_­t memset_­s swprintf_­s wcrtomb_­s
ctime_­s printf_­s swscanf_­s wcscat_­s
errno_­t qsort_­s tmpfile_­s wcscpy_­s
fopen_­s RSIZE_­MAX TMP_­MAX_­S wcsncat_­s
fprintf_­s rsize_­t tmpnam_­s wcsncpy_­s
freopen_­s scanf_­s vfprintf_­s wcsnlen_­s
fscanf_­s set_­constraint_­handler_­s vfscanf_­s wcsrtombs_­s
fwprintf_­s snprintf_­s vfwprintf_­s wcstok_­s
fwscanf_­s snwprintf_­s vfwscanf_­s wcstombs_­s
getenv_­s sprintf_­s vprintf_­s wctomb_­s
gets_­s sscanf_­s vscanf_­s wmemcpy_­s
gmtime_­s strcat_­s vsnprintf_­s wmemmove_­s
ignore_­handler_­s strcpy_­s vsnwprintf_­s wprintf_­s
L_­tmpnam_­s strerror_­s vsprintf_­s wscanf_­s
localtime_­s strerrorlen_­s vsscanf_­s
mbsrtowcs_­s strlen_­s vswprintf_­s

Заголовок не обязательно является исходным файлом, и последовательности, разделенные < и > в именах заголовков, не обязательно являются допустимыми именами исходного файла ([cpp.include]).

Это намеренное , что не существует C ++ заголовок для любого из этих заголовков C: , , .<stdatomic.h><stdnoreturn.h><threads.h>

Это запрещает практику, разрешенную в C, по предоставлению макроса маскировки в дополнение к прототипу функции. Единственный способ добиться эквивалентного встроенного поведения в C ++ - предоставить определение как внешнюю встроенную функцию.

В частности, включение стандартного заголовка <iso646.h> ни на <ciso646> что не влияет.

Эти ".h" заголовки сваливать все свои имена в глобальное пространство имен, в то время как новые формы сохраняют свои имена в пространстве имен std. Следовательно, новые формы являются предпочтительными формами для всех целей, кроме программ C ++, которые предназначены для строгой совместимости с C.

20.5.1.3 Freestanding implementations [compliance]

Определены два типа реализаций: hosted и freestanding ([intro.compliance]). Для размещенной реализации этот международный стандарт описывает набор доступных заголовков.

Автономная реализация имеет набор заголовков, определяемый реализацией. Этот набор должен включать как минимум заголовки, показанные в таблице 19.

Таблица 19 - Заголовки C ++ для автономных реализаций
Подпункт Заголовок (ы)
<ciso646>
[support.types] Типы <cstddef>
[support.limits] Свойства реализации <cfloat> <limits> <climits>
[cstdint] Целочисленные типы <cstdint>
[support.start.term] Начало и завершение <cstdlib>
[support.dynamic] Динамическое управление памятью <new>
[support.rtti] Идентификация типа <typeinfo>
[support.exception] Обработка исключений <exception>
[support.initlist] Списки инициализаторов <initializer_­list>
[support.runtime] Другая поддержка во время выполнения <cstdarg>
[meta] Типовые черты <type_­traits>
[atomics] Атомика <atomic>
[depr.cstdalign.syn], [depr.cstdbool.syn] Устаревшие заголовки <cstdalign> <cstdbool>

Прилагаемая версия заголовка объявляет , по меньшей мере функции , , , , и ( ). Остальные заголовки, перечисленные в этой таблице, должны соответствовать тем же требованиям, что и для размещенной реализации.<cstdlib> abortatexitat_­quick_­exitexit quick_­exit [support.start.term]

20.5.2 Using the library [using]

20.5.2.1 Overview [using.overview]

В этом разделе описывается, как программа на C ++ получает доступ к средствам стандартной библиотеки C ++. [using.headers] описывает эффекты во время фазы трансляции 4, а [using.linkage] описывает эффекты во время phase 8.

20.5.2.2 Headers [using.headers]

Сущности в стандартной библиотеке C ++ определены в заголовках, содержимое которых становится доступным для единицы перевода, когда она содержит соответствующие #include preprocessing directive.

Единица перевода может включать заголовки библиотеки в любом порядке (пункт [lex]). Каждый из них может быть включен более одного раза, при этом эффект не отличается от включения только один раз, за ​​исключением того, что эффект от включения одного<cassert> или другого <assert.h> зависит каждый раз от лексически актуального определения слова .NDEBUG173

Единица трансляции должна включать заголовок только вне любого объявления или определения и должна включать заголовок лексически перед первой ссылкой в ​​этой единице трансляции на любой из объектов, объявленных в этом заголовке. Диагностика не требуется.

Это то же самое, что и стандартная библиотека C.

20.5.2.3 Linkage [using.linkage]

Сущности в стандартной библиотеке C ++ имеют external linkage. Если не указано иное, объекты и функции имеют значение по умолчанию extern "C++" linkage ([dcl.link]).

Если имя из стандартной библиотеки C объявлена с внешним связыванием имеет или рычажный механизм реализации. Рекомендуется, чтобы реализация использовала для этой цели связь.extern "C"extern "C++"extern "C++"174

Объекты и функции, определенные в библиотеке и требуемые программой C ++, включаются в программу до ее запуска.

Единственный надежный способ объявить объект или сигнатуру функции из стандартной библиотеки C - это включить декларирующий ее заголовок, несмотря на широту, предоставленную в 7.1.4 стандарта C.

20.5.3 Requirements on types and expressions [utility.requirements]

[utility.arg.requirements] описывает требования к типам и выражениям, используемым для создания экземпляров шаблонов, определенных в стандартной библиотеке C ++. [swappable.requirements] описывает требования к заменяемым типам и заменяемым выражениям. [nullablepointer.requirements] описывает требования к типам, подобным указателям, которые поддерживают нулевые значения. [hash.requirements] описывает требования к объектам хэш-функции. [allocator.requirements] описывает требования к распределителям памяти.

20.5.3.1 Template argument requirements [utility.arg.requirements]

Определения шаблонов в стандартной библиотеке C ++ относятся к различным именованным требованиям, подробности которых изложены в таблицах 20-27. В этих таблицах T - объектный или ссылочный тип, предоставляемый программой C ++, создающей экземпляр шаблона; a,, bи c являются значениями типа (возможно const) T; s и t являются изменяемыми значениями типа T; u обозначает идентификатор; rv является значением типа T; и v является l-значением типа (возможно const) T или r-значением типа const T.

Как правило, конструктор по умолчанию не требуется. Определенные сигнатуры функций-членов класса контейнера указываются T() в качестве аргумента по умолчанию. T() должно быть четко определенным выражением ([dcl.init]), если одна из этих подписей вызывается с использованием default argument.

Таблица 20 - EqualityComparable требования
Выражение Тип возврата Требование
a == b конвертируемый в bool == является отношением эквивалентности, то есть обладает следующими свойствами:
  • Для всех a, a == a.

  • Если a == b, то b == a.

  • Если a == b и b == c, то a == c.

Таблица 21 - LessThanComparable требования
Выражение Тип возврата Требование
a < b конвертируемый в bool < это strict weak ordering relation

Таблица 22 - DefaultConstructible требования
Выражение Пост-условие
T t; объект t инициализирован по умолчанию
T u{}; объект u инициализирован значением или агрегатом
T()
T{}
объект типа T инициализируется значением или агрегатом

Таблица 23 - MoveConstructible требования
Выражение Пост-условие
T u = rv; u эквивалентно значению rv до постройки
T(rv) T(rv) эквивалентно значению rv до постройки
rvсостояние не указано [ Note: rv должно все еще соответствовать требованиям библиотечного компонента, который его использует. Операции, перечисленные в этих требованиях, должны работать, как указано, независимо от того rv , были они перемещены или нет. ] end note

Таблица 24 - CopyConstructible требования (в дополнение к MoveConstructible)
Выражение Пост-условие
T u = v; значение v не изменилось и эквивалентно u
T(v) значение v не изменилось и эквивалентно T(v)

Таблица 25 - MoveAssignable требования
Выражение Тип возврата Возвращаемое значение Пост-условие
t = rv T& t Если t и rv не относятся к одному и тому же объекту, t эквивалентно значению rv до присвоения
rvсостояние не указано. [ Note:  rv должен по-прежнему соответствовать требованиям библиотечного компонента, который его использует, независимо от того, относится ли он к одному t и rv тому же объекту или нет . Операции, перечисленные в этих требованиях, должны работать, как указано, независимо от того rv , были они перемещены или нет. ] end note

Таблица 26 - CopyAssignable требования (в дополнение к MoveAssignable)
Выражение Тип возврата Возвращаемое значение Пост-условие
t = v T& t t эквивалентно v, значение v не изменяется

Таблица 27 - Destructible требования
Выражение Пост-условие
u.~T() Все ресурсы, принадлежащие владельцу u , возвращаются, никаких исключений не распространяется.

20.5.3.2 Swappable requirements [swappable.requirements]

В этом подпункте приведены определения заменяемых типов и выражений. В этих определениях let t обозначает выражение типа T, а let u обозначает выражение типа U.

Объект t является swappable with объектом u тогда и только тогда, когда:

  • выражения swap(t, u) и swap(u, t) действительны при оценке в контексте, описанном ниже, и

  • эти выражения имеют следующие эффекты:

    • объект, на который ссылается, t имеет ценность, первоначально принадлежащую u и

    • объект, на который ссылается, u имеет первоначальное значение t.

Контекст , в котором swap(t, u) и swap(u, t) оцениваются должен гарантировать , что бинарная функция не-член с именем «своп» выбирается с помощью overload resolution по набору кандидатов , который включает в себя:

[ Note: Если T и U являются как фундаментальными типами, так и массивами фундаментальных типов и объявления из заголовка <utility> находятся в области видимости, общий поисковый набор, описанный выше, эквивалентен поиску по квалифицированному имени, применяемому к выражению std​::​swap(t, u) или по std​::​swap(u, t) мере необходимости. ] end note

[ Note: Не указано, включает ли компонент библиотеки, требующий замены, заголовок, <utility> чтобы гарантировать соответствующий контекст оценки. ] end note

Rvalue или lvalue t есть swappable тогда и только тогда, когда их t можно заменить любым rvalue или lvalue, соответственно, типа T.

Тип X удовлетворяющего любой из iterator requirements удовлетворяют требования , ValueSwappable если для любого объекта разыменовываемого x типа X, *x является заменой.

[ Example: Код пользователя может гарантировать, что оценка swap вызовов выполняется в соответствующем контексте при различных следующих условиях:

#include <utility>

// Requires: std​::​forward<T>(t) shall be swappable with std​::​forward<U>(u).
template <class T, class U>
void value_swap(T&& t, U&& u) {
  using std::swap;
  swap(std::forward<T>(t), std::forward<U>(u)); // OK: uses “swappable with” conditions
                                                // for rvalues and lvalues
}

// Requires: lvalues of T shall be swappable.
template <class T>
void lv_swap(T& t1, T& t2) {
  using std::swap;
  swap(t1, t2);                                 // OK: uses swappable conditions for
}                                               // lvalues of type T

namespace N {
  struct A { int m; };
  struct Proxy { A* a; };
  Proxy proxy(A& a) { return Proxy{ &a }; }

  void swap(A& x, Proxy p) {
    std::swap(x.m, p.a->m);                     // OK: uses context equivalent to swappable
                                                // conditions for fundamental types
  }
  void swap(Proxy p, A& x) { swap(x, p); }      // satisfy symmetry constraint
}

int main() {
  int i = 1, j = 2;
  lv_swap(i, j);
  assert(i == 2 && j == 1);

  N::A a1 = { 5 }, a2 = { -5 };
  value_swap(a1, proxy(a2));
  assert(a1.m == -5 && a2.m == 5);
}

end example]

20.5.3.3 NullablePointer requirements [nullablepointer.requirements]

NullablePointer Типа является указателем типа типа , который поддерживает нулевые значения. Тип P соответствует требованиям, NullablePointer если:

  • P удовлетворяет требованиям EqualityComparable, DefaultConstructible, CopyConstructible, CopyAssignable, и Destructible,

  • lvalues типа P являются swappable,

  • выражения, показанные в таблице 28 , действительны и имеют указанную семантику, и

  • P удовлетворяет всем остальным требованиям данного подпункта.

Объект типа, инициализированный значением, P создает нулевое значение типа. Нулевое значение должно быть эквивалентно только самому себе. Инициализированный по умолчанию объект типа P может иметь неопределенное значение. [ Note: Операции с неопределенными значениями могут вызывать неопределенное поведение. ] end note

Объект p типа P может быть contextually converted to bool. Эффект должен быть таким, как если бы p != nullptr он был оценен вместо p.

Никакая операция, которая является частью NullablePointer требований, не должна завершаться через исключение.

В таблице 28, u обозначает идентификатор, t обозначает не-const объекта типа P, a и b обозначают значение типа (возможно const) P, и np обозначает значение типа (возможно const) std​::​nullptr_­t.

Таблица 28 - NullablePointer требования
Выражение Тип возврата Операционная семантика
P u(np);
Postconditions: u == nullptr
P u = np;
P(np) Postconditions: P(np) == nullptr
t = np P& Postconditions: t == nullptr
a != b контекстно конвертируемый в bool !(a == b)
a == np контекстно конвертируемый в bool a == P()
np == a
a != np контекстно конвертируемый в bool !(a == np)
np != a

20.5.3.4 Hash requirements [hash.requirements]

Тип H соответствует Hash требованиям, если:

Given Key - тип аргумента для функциональных объектов типа H, в Table 29 h - значение типа (возможно const) H, u это lvalue типа Keyи k значение типа, конвертируемого в (возможно const) Key.

Таблица 29 - Hash требования
Выражение Тип возврата Требование
h(k) size_­t Возвращаемое значение должно зависеть только от аргумента k на протяжении всей программы. [ Note: Таким образом, все вычисления выражения h(k) с одинаковым значением для k дают одинаковый результат для данного выполнения программы. ] [ Для двух разных значений и вероятность того, что и сравнить равные, должна быть очень мала и приближается . ] end noteNote: t1 t2 h(t1) h(t2) 1.0 / numeric_­limits<size_­t>​::​max() end note
h(u) size_­t Изменять не буду u.

20.5.3.5 Allocator requirements [allocator.requirements]

Библиотека описывает стандартный набор требований allocators, которые представляют собой объекты типа класса, которые инкапсулируют информацию о модели распределения. Эта информация включает в себя сведения о типах указателей, типе их различия, типе размера объектов в этой модели распределения, а также о примитивах выделения и освобождения памяти для нее. Все перечисленные string types, containers (кроме массива), строковые буферы и строковые потоки (п [input.output]) и match_­results параметризуются в терминах распределителей.

Шаблон класса allocator_­traits предоставляет единый интерфейс для всех типов распределителей. В таблице 30 описаны типы, управляемые с помощью распределителей. В таблице 31 описаны требования к типам распределителя и, следовательно, к типам, используемым для создания экземпляров allocator_­traits. Требование является необязательным, если последний столбец таблицы 31 указывает значение по умолчанию для данного выражения. В allocator_­traits шаблоне стандартной библиотеки необязательное требование, которое не предоставляется распределителем, заменяется указанным выражением по умолчанию. Специализация пользователя allocator_­traits может предоставлять различные значения по умолчанию и может предоставлять значения по умолчанию для требований, отличных от основного шаблона. В таблицах 30 и 31использование move и forward всегда относится к std​::​move и std​::​forward, соответственно.

Таблица 30 - Описательные определения переменных
ПеременнаяОпределение
T, U, C любой - cvнеквалифицированный тип объекта ([basic.types])
X класс Allocator для типа T
Y соответствующий класс Allocator для типа U
XX тип allocator_­traits<X>
YY тип allocator_­traits<Y>
a, a1, a2 lvalues ​​типа X
u имя объявляемой переменной
b значение типа Y
c указатель типа, C* через который допустимо косвенное обращение
p значение типа XX​::​pointer, полученное при вызове a1.allocate, где a1 == a
q значение типа, XX​::​const_­pointer полученное преобразованием из значения p.
w значение типа, XX​::​void_­pointer полученное преобразованием из значения p
x значение типа, XX​::​const_­void_­pointer полученное преобразованием из значения q или значения w
y значение типа, XX​::​const_­void_­pointer полученное преобразованием из значения результата YY​::​allocate, или значение типа (возможно const) std​::​nullptr_­t.
n значение типа XX​::​size_­type.
Args пакет параметров шаблона
args пакет параметров функции с шаблоном Args&&

Таблица 31 - Требования к распределителю
ВыражениеТип возвратаУтверждение / примечаниеДефолт
до / после состояния
X​::​pointer T*
X​::​const_­pointer X​::​pointer конвертируется в X​::​const_­pointer pointer_­traits<X​::​​pointer>​::​​rebind<const T>
X​::​void_­pointer
Y​::​void_­pointer
X​::​pointer конвертируется в X​::​void_­pointer. X​::​void_­pointer и Y​::​void_­pointer однотипны. pointer_­traits<X​::​​pointer>​::​​rebind<void>
X​::​const_­void_­pointer
Y​::​const_­void_­pointer
X​::​pointer, X​::​const_­pointerИ X​::​void_­pointer могут быть конвертированы в X​::​const_­void_­pointer. X​::​const_­void_­pointer и Y​::​const_­void_­pointer однотипны. pointer_­traits<X​::​​pointer>​::​​rebind<const void>
X​::​value_­type Идентично T
X​::​size_­type беззнаковый целочисленный тип тип, который может представлять размер самого большого объекта в модели распределения. make_­unsigned_­t<X​::​​difference_­type>
X​::​difference_­type знаковый целочисленный тип тип, который может представлять разницу между любыми двумя указателями в модели распределения. pointer_­traits<X​::​​pointer>​::​​difference_­type
typename X​::​template rebind<U>​::​other Y Для всех U (в том числе T) Y​::​template rebind<T>​::​other есть X. См. Примечание A ниже.
*p T&
*q const T& *q относится к тому же объекту, что и *p
p->m тип T​::​m Requires: (*p).m четко определено. эквивалентно (*p).m
q->m тип T​::​m Requires: (*q).m четко определено. эквивалентно (*q).m
static_­cast<​X​::​pointer​>(w) X​::​pointer static_­cast<X​::​pointer>(w) == p
static_­cast<​X​::​const_­pointer​>(x) X​::​const_­pointer static_­cast< X​::​const_­pointer​>(x) == q
pointer_­traits<​X​::​pointer​>​::​pointer_­to(r) X​::​pointer
a.allocate(n) X​::​pointer Память выделяется для n объектов типа, T но объекты не создаются. allocate может вызвать соответствующее исключение.175 [ Note: Если n == 0, возвращаемое значение не указано. ] end note
a.allocate(n, y) X​::​pointer То же, что и a.allocate(n). Использование y не указано, но оно предназначено для помощи в местности. a.allocate(n)
a.deallocate(p,n) (не используется) Requires: p должен быть значением, возвращенным более ранним вызовом allocate , который не был аннулирован промежуточным вызовом deallocate. n должен соответствовать значению, переданному allocate для получения этой памяти.
Throws: Ничего такого.
a.max_­size() X​::​size_­type наибольшее значение, которое может быть значимо передано в X​::​allocate() numeric_­limits<size_­type>​::​max() / sizeof​(value_­type)
a1 == a2 bool возвращается true только в том случае, если память, выделенная каждым из них, может быть освобождена через другую. operator== должен быть рефлексивным, симметричным и транзитивным и не должен выходить через исключение.
a1 != a2 bool такой же как !(a1 == a2)
a == b bool такой же как a == Y​::​rebind<T>​::​other(b)
a != b bool такой же как !(a == b)
X u(a);
X u = a;
Не должен выходить из-за исключения.
Postconditions: u == a
X u(b); Не должен выходить из-за исключения.
Postconditions: Y(u) == b, u == X(b)
X u(std​::​move(a));
X u = std​::​move(a);
Не должен выходить из-за исключения.
Postconditions: u равно предыдущему значению a.
X u(std​::​move(b)); Не должен выходить из-за исключения.
Postconditions: u равно предыдущему значению X(b).
a.construct(c, args) (не используется) Effects: Создает объект типа C в c ​::​new ((void*)c) C(forward<​Args>​(args)...)
a.destroy(c) (не используется) Effects: Уничтожает объект на c c->~C()
a.select_­on_­container_­copy_­construction() X Обычно возвращает либо, a либо X() return a;
X​::​propagate_­on_­container_­copy_­assignment Идентичен или производный от true_­type или false_­type true_­type только если распределитель типа X должен быть скопирован, когда клиентскому контейнеру назначено копирование. См. Примечание B ниже. false_­type
X​::​propagate_­on_­container_­move_­assignment Идентичен или производный от true_­type или false_­type true_­type только в том случае, если распределитель типа X должен быть перемещен при назначении перемещения клиентскому контейнеру. См. Примечание B ниже. false_­type
X​::​propagate_­on_­- container_­swap Идентичен или производный от true_­type или false_­type true_­type только если распределитель типа X должен быть заменен при замене клиентского контейнера. См. Примечание B ниже. false_­type
X​::​is_­always_­equal Идентичен или производный от true_­type или false_­type true_­type только тогда , когда выражение a1 == a2 гарантированно будет true для любых двух (возможно const) значений a1, a2 типа X. is_­empty<X>​::​​type

Примечание A. Шаблон класса-члена rebind в приведенной выше таблице фактически является шаблоном typedef. [ Note: В общем, если имя Allocator привязано к SomeAllocator<T>, то Allocator​::​rebind<U>​::​other имеет тот же тип, что и SomeAllocator<U>, где SomeAllocator<T>​::​value_­type есть T и SomeAllocator<U>​::​​value_­type есть U. ] Если является экземпляром шаблона класса формы , где ноль или более аргументов типа и не предоставляет шаблон элемента, стандартный шаблон используется вместо него по умолчанию. Для типов распределителей, которые не являются экземплярами шаблонов приведенной выше формы, значение по умолчанию не предоставляется. end noteAllocator SomeAllocator<T, Args> Args Allocator rebind allocator_­traits SomeAllocator<U, Args> Allocator​::​​rebind<U>​::​other

Примечание B: Если X​::​propagate_­on_­container_­copy_­assignment​::​value есть true, X должно удовлетворять CopyAssignable requirements и операция копирования не должна вызывать исключений. Если X​::​propagate_­on_­container_­move_­assignment​::​value есть true, X должно удовлетворять, MoveAssignable requirements и операция перемещения не должна вызывать исключений. Если X​::​propagate_­on_­container_­swap​::​value есть true, lvalues ​​типа X должны быть, swappable и swap операция не должна вызывать исключений.

Тип распределителя X должен удовлетворять требованиям CopyConstructible. X​::​pointer, X​::​const_­pointer, X​::​void_­pointer, И X​::​const_­void_­pointer типы должны удовлетворять требования NullablePointer. Никакой конструктор, функция сравнения, операция копирования, операция перемещения или операция обмена для этих типов указателей не должны завершаться через исключение. X​::​pointer а X​::​const_­pointer также должны удовлетворять требованиям а random access iterator и а contiguous iterator.

Пусть x1 и x2 обозначают объекты (возможно , различные) типов X​::​void_­pointer, X​::​const_­void_­pointer, X​::​pointerили X​::​const_­pointer. Тогда x1 и x2 являются equivalently-valued значениями указателей, если и только если оба x1 и x2 могут быть явно преобразованы в два соответствующих объекта px1 и px2 типа X​::​const_­pointerс использованием последовательности static_­casts, использующей только эти четыре типа, и выражение px1 == px2 оценивается как true.

Пусть w1 и w2 обозначают объекты типа X​::​void_­pointer. Тогда для выражений

w1 == w2
w1 != w2

один или оба объекта могут быть заменены объектом типаX​::​const_­void_­pointer с эквивалентным значением без изменения семантики.

Пусть p1 и p2 обозначают объекты типа X​::​pointer. Тогда для выражений

p1 == p2
p1 != p2
p1 < p2
p1 <= p2
p1 >= p2
p1 > p2
p1 - p2

один или оба объекта могут быть заменены объектом типаX​::​const_­pointer с эквивалентным значением без изменения семантики.

Распределитель может ограничивать типы, для которых он может быть создан, и аргументы, для которых он construct или его destroy члены могут вызываться. Если тип не может использоваться с конкретным распределителем, класс распределителя или вызов construct или destroy могут не создать экземпляра.

[ Example: Ниже приведен шаблон класса распределителя, поддерживающий минимальный интерфейс, удовлетворяющий требованиям таблицы 31:

template <class Tp>
struct SimpleAllocator {
  typedef Tp value_type;
  SimpleAllocator(ctor args);

  template <class T> SimpleAllocator(const SimpleAllocator<T>& other);

  Tp* allocate(std::size_t n);
  void deallocate(Tp* p, std::size_t n);
};

template <class T, class U>
bool operator==(const SimpleAllocator<T>&, const SimpleAllocator<U>&);
template <class T, class U>
bool operator!=(const SimpleAllocator<T>&, const SimpleAllocator<U>&);

end example]

Если выравнивание, связанное с конкретным сверхвыровненным типом, не поддерживается распределителем, создание экземпляра распределителя для этого типа может завершиться ошибкой. Распределитель также может молча игнорировать запрошенное выравнивание. [ Note: Кроме того, функция-член allocate для этого типа может завершиться ошибкой, выбрасывая объект типа bad_­alloc. ]end note

Предполагается, что это a.allocate будет эффективное средство выделения одного объекта типа T, даже если sizeof(T) он невелик. То есть контейнеру не нужно поддерживать свой собственный список свободных мест.

20.5.3.5.1 Allocator completeness requirements [allocator.requirements.completeness]

Если X это класс распределителя для типа T, X дополнительно удовлетворяет требованиям полноты распределителя, если, T является ли тип полным или нет :

20.5.4 Constraints on programs [constraints]

20.5.4.1 Overview [constraints.overview]

В этом разделе описаны ограничения для программ C ++, использующих возможности стандартной библиотеки C ++. Следующие подпункты определяют ограничения на использование программой namespaces, ее использование различных reserved names, ее использование headers, ее использование стандартных библиотечных классов в качестве базовых классов ([derived.classes]), ее определения replacement functionsи ее установку handler functions во время выполнения.

20.5.4.2 Namespace use [namespace.constraints]

20.5.4.2.1 Namespace std [namespace.std]

Поведение программы C ++ не определено, если она добавляет объявления или определения в пространство имен std или в пространство имен в пространстве имен, std если не указано иное. Программа может добавить специализацию шаблона для любого шаблона стандартной библиотеки в пространство имен std только в том случае, если объявление зависит от определяемого пользователем типа, а специализация соответствует требованиям стандартной библиотеки для исходного шаблона и не запрещена явно.176

Поведение программы на C ++ не определено, если она объявляет

  • явная специализация любой функции-члена шаблона класса стандартной библиотеки, или

  • явная специализация любого шаблона функции-члена стандартного библиотечного класса или шаблона класса, или

  • явная или частичная специализация любого шаблона класса-члена стандартного библиотечного класса или шаблона класса, или

  • руководство по вычету для любого стандартного шаблона класса библиотеки.

Программа может явно создать экземпляр шаблона, определенного в стандартной библиотеке, только в том случае, если объявление зависит от имени определяемого пользователем типа и создание экземпляра соответствует требованиям стандартной библиотеки для исходного шаблона.

Единица трансляции не должна объявлять пространство имен std как встроенное пространство имен ([namespace.def]).

Любой библиотечный код, который создает экземпляры других библиотечных шаблонов, должен быть подготовлен для адекватной работы с любой специализацией, задаваемой пользователем, которая соответствует минимальным требованиям настоящего международного стандарта.

20.5.4.2.2 Namespace posix [namespace.posix]

Поведение программы C ++ не определено, если она добавляет объявления или определения в пространство имен posix или в пространство имен в пространстве имен, posix если не указано иное. Пространство имен posix зарезервировано для использования ISO / IEC 9945 и другими стандартами POSIX.

20.5.4.2.3 Namespaces for future standardization [namespace.future]

Пространства имен верхнего уровня с именем, начинающимся с std непустой последовательности цифр и за которым следует непустая последовательность цифр, зарезервированы для будущей стандартизации. Поведение программы C ++ не определено, если она добавляет объявления или определения в такое пространство имен. [ Example: Пространство имен верхнего уровня std2 зарезервировано для использования в будущих версиях настоящего стандарта. ] end example

20.5.4.3 Reserved names [reserved.names]

Стандартная библиотека C ++ резервирует следующие типы имен:

  • макросы

  • глобальные имена

  • имена с внешней связью

Если программа объявляет или определяет имя в контексте, в котором оно зарезервировано, кроме случаев, явно разрешенных этим пунктом, ее поведение не определено.

20.5.4.3.1 Zombie names [zombie.names]

В пространстве имен stdследующие имена зарезервированы для предыдущей стандартизации:

20.5.4.3.2 Macro names [macro.names]

Единица трансляции, которая включает заголовок стандартной библиотеки, не должна#define или не #undef объявляется в каком-либо заголовке стандартной библиотеки.

Единица перевода не должна #define или не должна быть #undef лексически идентична ключевым словам, идентификаторам, перечисленным в Таблице 4, или attribute-tokens описанным в [dcl.attr].

20.5.4.3.3 External linkage [extern.names]

Каждое имя, объявленное как объект с внешней связью в заголовке, зарезервировано для реализации, чтобы обозначить этот объект библиотеки с внешней связью 177 как в пространстве имен, так std и в глобальном пространстве имен.

Каждая глобальная сигнатура функции, объявленная с внешней связью в заголовке, зарезервирована для реализации, чтобы обозначить эту сигнатуру функции с внешней связью.178

Каждое имя из стандартной библиотеки C, объявленное с внешней связью , зарезервировано для реализации для использования в качестве имени со связью как в пространстве имен, так и в глобальном пространстве имен.extern "C" std

Каждая сигнатура функции из стандартной библиотеки C, объявленной с внешней связью, зарезервирована для реализации для использования в качестве сигнатуры функции с обоими extern "C" и extern "C++" связью179 или как имя области пространства имен в глобальном пространстве имен.

Список таких зарезервированных имен включает errno, объявлен или определен в .<cerrno>

Список таких зарезервированных сигнатур функций с внешней связью включает setjmp(jmp_­buf), объявленные или определенные в , и , объявленные или определенные в .<csetjmp>va_­end(va_­list)<cstdarg>

Сигнатуры функций, объявленные в , и всегда зарезервированы, несмотря на ограничения, наложенные в подпункте 4.5.1 Поправки 1 к Стандарту C для этих заголовков.<cuchar><cwchar><cwctype>

20.5.4.3.4 Types [extern.types]

Для каждого типа T из стандартной библиотеки C180 типы ​::​T и std​::​T зарезервированы для реализации и, если они определены, ​::​T должны быть идентичны std​::​T.

Эти типы clock_­t, div_­t, FILE, fpos_­t, lconv, ldiv_­t, mbstate_­t, ptrdiff_­t, sig_­atomic_­t, size_­t, time_­t, tm, va_­list, wctrans_­t, wctype_­t, и wint_­t.

20.5.4.3.5 User-defined literal suffixes [usrlit.suffix]

Literal suffix identifiers которые не начинаются с подчеркивания, зарезервированы для будущей стандартизации.

20.5.4.4 Headers [alt.headers]

Если файл с именем, эквивалентным имени производного файла для одного из заголовков стандартной библиотеки C ++, не предоставляется как часть реализации, и файл с таким именем помещается в любое из стандартных мест для исходного файла included, поведение не определено.

20.5.4.5 Derived classes [derived.classes]

Сигнатуры виртуальных функций-членов, определенные для базового класса в стандартной библиотеке C ++, могут быть переопределены в производном классе, определенном в программе ( ).[class.virtual]

20.5.4.6 Replacement functions [replacement.functions]

Пункты [language.support] до [thread] и Приложение [depr] описывают поведение множества функций, определенных стандартной библиотекой C ++. Однако при некоторых обстоятельствах некоторые из этих описаний функций также применимы к функциям замены, определенным в программе ([definitions]).

Программа на C ++ может предоставить определение для любой из следующих сигнатур функции распределения динамической памяти, объявленных в header <new> ([basic.stc.dynamic], [support.dynamic]):

operator new(std::size_t)
operator new(std::size_t, std::align_val_t)
operator new(std::size_t, const std::nothrow_t&)
operator new(std::size_t, std::align_val_t, const std::nothrow_t&)

operator delete(void*)
operator delete(void*, std::size_t)
operator delete(void*, std::align_val_t)
operator delete(void*, std::size_t, std::align_val_t)
operator delete(void*, const std::nothrow_t&)
operator delete(void*, std::align_val_t, const std::nothrow_t&)

operator new[](std::size_t)
operator new[](std::size_t, std::align_val_t)
operator new[](std::size_t, const std::nothrow_t&)
operator new[](std::size_t, std::align_val_t, const std::nothrow_t&)

operator delete[](void*)
operator delete[](void*, std::size_t)
operator delete[](void*, std::align_val_t)
operator delete[](void*, std::size_t, std::align_val_t)
operator delete[](void*, const std::nothrow_t&)
operator delete[](void*, std::align_val_t, const std::nothrow_t&)

Определения программы используются вместо версий по умолчанию, предоставляемых реализацией ([support.dynamic]). Такая замена происходит до запуска программы ([basic.def.odr], [basic.start]). Объявления программы не должны указываться как inline. Диагностика не требуется.

20.5.4.7 Handler functions [handler.functions]

Стандартная библиотека C ++ предоставляет версию по умолчанию для следующей функции-обработчика (пункт [language.support]):

  • terminate_­handler

Программа на C ++ может устанавливать различные функции-обработчики во время выполнения, предоставляя указатель на функцию, определенную в программе или библиотеке, в качестве аргумента для (соответственно):

См. Также подпункты [alloc.errors]Ошибки выделения памяти и [support.exception]Обработка исключений.

Программа на C ++ может получить указатель на текущую функцию-обработчик, вызвав следующие функции:

Вызов set_­* и get_­* функция не влечет за собой гонку данных. Вызов любой из set_­* функций должен синхронизироваться с последующими вызовами той же set_­* функции и соответствующей get_­* функции.

20.5.4.8 Other functions [res.on.functions]

В некоторых случаях (функции замены, функции обработчика, операции с типами, используемыми для создания экземпляров компонентов шаблона стандартной библиотеки) стандартная библиотека C ++ зависит от компонентов, предоставляемых программой C ++. Если эти компоненты не соответствуют их требованиям, настоящий международный стандарт не предъявляет требований к реализации.

В частности, эффекты не определены в следующих случаях:

  • for replacement functions, если установленная функция замены не реализует семантику применимого Required behavior: абзаца.

  • для функций-обработчиков ([new.handler], [terminate.handler]), если установленная функция-обработчик не реализует семантику соответствующего Required behavior: абзаца

  • для типов , используемых в качестве аргументов шаблона при создании экземпляра шаблона компонента, если операции по типу не реализуют семантику применимых требований подпункта ([allocator.requirements], [container.requirements], [iterator.requirements], [algorithms.requirements], [numeric.requirements]). Операции с такими типами могут сообщать об ошибке, вызывая исключение, если не указано иное.

  • если какая-либо функция замены, функция обработчика или операция деструктора завершается через исключение, если иное не разрешено в соответствующем Required behavior: абзаце.

  • если incomplete type используется в качестве аргумента шаблона при создании экземпляра компонента шаблона, если это специально не разрешено для этого компонента.

20.5.4.9 Function arguments [res.on.arguments]

Каждое из следующих действий применяется ко всем аргументам функций, определенных в стандартной библиотеке C ++, если явно не указано иное.

  • Если аргумент функции имеет недопустимое значение (например, значение вне домена функции или указатель, недопустимый для предполагаемого использования), поведение не определено.

  • Если аргумент функции описывается как массив, указатель, фактически переданный функции, должен иметь такое значение, чтобы все вычисления адресов и доступ к объектам (это было бы действительным, если бы указатель действительно указывал на первый элемент такого массива) на самом деле действительны.

  • Если аргумент функции привязывается к параметру ссылки rvalue, реализация может предположить, что этот параметр является уникальной ссылкой на этот аргумент. [ Note: Если параметр является универсальным параметром формы T&& иA привязано lvalue типа , аргумент привязывается к ссылке lvalue ([temp.deduct.call]) и, таким образом, не охвачен предыдущим предложением. ] [ Если программа преобразует lvalue в xvalue, передавая это lvalue библиотечной функции (например, вызывая функцию с аргументом ), программа фактически просит эту функцию рассматривать это lvalue как временное. Реализация позволяет оптимизировать проверки наложения псевдонимов, которые могут потребоваться, если аргумент был lvalue. ] end noteNote: std​::​move(x) end note

20.5.4.10 Library object access [res.on.objects]

Поведение программы не определено, если вызовы стандартных библиотечных функций из разных потоков могут вызвать гонку данных. Условия, при которых это может произойти, указаны в [res.on.data.races]. [ Note: Изменение объекта стандартного типа библиотеки, который совместно используется потоками, рискует неопределенным поведением, если только объекты этого типа явно не указаны как доступные для совместного использования без гонок данных или пользователь не предоставит механизм блокировки. ] end note

Если осуществляется доступ к объекту стандартного библиотечного типа, и начало объекта lifetime не происходит до доступа или доступ не происходит до конца времени существования объекта, поведение не определено, если не указано иное. [ Note: Это применимо даже к таким объектам, как мьютексы, предназначенным для синхронизации потоков. ]end note

20.5.4.11 Requires paragraph [res.on.required]

Нарушение предварительных условий, указанных вRequires: абзаце функции, приводит к неопределенному поведению, если вThrows: абзаце функции не указано, что при нарушении предварительного условия генерируется исключение.

20.5.5 Conforming implementations [conforming]

20.5.5.1 Overview [conforming.overview]

В этом разделе описываются ограничения и широта реализаций стандартной библиотеки C ++.

Использование заголовков в реализации обсуждается в [res.on.headers]: использование макросов в [res.on.macro.definitions], функций, не являющихся членами, функций- [global.functions]членов в [member.functions], предотвращения гонки данных в [res.on.data.races], спецификаторов доступа в [protection.within.classes], производного класса в [derivation]и исключений в [res.on.exception.handling].

20.5.5.2 Headers [res.on.headers]

Заголовок C ++ может включать другие заголовки C ++. Заголовок C ++ должен содержать объявления и определения, которые появляются в его синопсисе. Заголовок C ++, показанный в его синопсисе как включающий другие заголовки C ++, должен содержать объявления и определения, которые появляются в резюме этих других заголовков.

Некоторые типы и макросы определены более чем в одном заголовке. Каждый такой объект должен быть определен таким образом, чтобы любой заголовок, который его определяет, мог быть включен после любого другого заголовка, который также его определяет ([basic.def.odr]).

Они C standard library headers должны включать только соответствующий заголовок стандартной библиотеки C ++, как описано в [headers].

20.5.5.3 Restrictions on macro definitions [res.on.macro.definitions]

Имена и подписи глобальных функций, описанные в [contents] , зарезервированы для реализации.

Все объектно-подобные макросы, определенные стандартной библиотекой C и описанные в этом разделе как расширяющиеся до целочисленных константных выражений, также подходят для использования в директивах предварительной обработки, если явно не указано иное. #if

20.5.5.4 Non-member functions [global.functions]

Не указано, определены ли какие-либо функции, не являющиеся членами, в стандартной библиотеке C ++ как inline.

Вызов сигнатуры функции, не являющейся членом, описанной в разделах [language.support] по [thread] и в приложении, [depr] должен вести себя так, как если бы реализация не объявила никаких дополнительных сигнатур функций, не являющихся членами.181

Реализация не должна объявлять сигнатуру функции, не являющейся членом, с дополнительными аргументами по умолчанию.

Если не указано иное, вызовы, выполняемые функциями в стандартной библиотеке для неоператорных функций, не являющихся членами, не используют функции из другого пространства имен, которые можно найти с помощью argument-dependent name lookup ([basic.lookup.argdep]). [ Note: Фраза «если не указано иное» применяется к таким случаям, как замена с требованиями ([swappable.requirements]). Исключение для перегруженных операторов разрешает поиск в зависимости от аргументов в следующих случаях ostream_­iterator​::​operator=:

Effects:

*out_stream << value;
if (delim != 0)
  *out_stream << delim;
return *this;

end note]

Допустимая программа на C ++ всегда вызывает ожидаемую библиотечную функцию, не являющуюся членом. Реализация также может определять дополнительные функции, не являющиеся членами, которые в противном случае не вызывались бы действительной программой C ++.

20.5.5.5 Member functions [member.functions]

Не указано, определены ли какие-либо функции-члены в стандартной библиотеке C ++ как inline.

Для невиртуальной функции-члена, описанной в стандартной библиотеке C ++, реализация может объявить другой набор сигнатур функций-членов при условии, что любой вызов функции-члена, который выберет перегрузку из набора объявлений, описанных в этом международном стандарте, ведет себя как если бы была выбрана эта перегрузка. [ Note: Например, реализация может добавлять параметры со значениями по умолчанию или заменять функцию-член с аргументами по умолчанию двумя или более функциями-членами с эквивалентным поведением или добавлять дополнительные подписи для имени функции-члена. ]end note

20.5.5.6 Constexpr functions and constructors [constexpr.functions]

Этот международный стандарт явно требует, чтобы определенные стандартные библиотечные функции были constexpr. Реализация не должна объявлять какую-либо сигнатуру стандартной библиотечной функции, constexpr за исключением тех, где это явно требуется. В любом заголовке, который предоставляет любые не определяющие объявления функций или конструкторов constexpr, реализация должна предоставлять соответствующие определения.

20.5.5.7 Requirements for stable algorithms [algorithm.stable]

Когда в требованиях к алгоритму указано, что он «стабилен» без дальнейшей разработки, это означает:

  • Для sort алгоритмов сохраняется относительный порядок эквивалентных элементов.

  • Для алгоритмов remove и copy сохраняется относительный порядок элементов, которые не удаляются.

  • Для merge алгоритмов для эквивалентных элементов в исходных двух диапазонах элементы из первого диапазона (с сохранением их исходного порядка) предшествуют элементам из второго диапазона (с сохранением их исходного порядка).

20.5.5.8 Reentrancy [reentrancy]

За исключением случаев, когда это явно указано в этом международном стандарте, это определяется реализацией, какие функции в стандартной библиотеке C ++ могут быть повторно введены рекурсивно.

20.5.5.9 Data race avoidance [res.on.data.races]

В этом разделе указаны требования, которым должны соответствовать реализации для предотвращения data races. Каждая стандартная библиотечная функция должна соответствовать каждому требованию, если не указано иное. Реализации могут предотвратить гонку данных в случаях, отличных от указанных ниже.

Функция стандартной библиотеки C ++ не должна прямо или косвенно обращаться к объектам ([intro.multithread]), доступным потокам, отличным от текущего потока, если к объектам не осуществляется прямой или косвенный доступ через аргументы функции, в том числе this.

Функция стандартной библиотеки C ++ не должна прямо или косвенно изменять объекты ([intro.multithread]), доступные потокам, отличным от текущего потока, если к объектам не осуществляется прямой или косвенный доступ через неконстантные аргументы функции, включая this.

[ Note: Это означает, например, что реализации не могут использовать статический объект для внутренних целей без синхронизации, потому что это может вызвать гонку данных даже в программах, которые явно не разделяют объекты между потоками. ] end note

Функция стандартной библиотеки C ++ не должна обращаться к объектам, косвенно доступным через ее аргументы или через элементы аргументов контейнера, кроме как путем вызова функций, требуемых ее спецификацией, для этих элементов контейнера.

Операции с итераторами, полученные путем вызова контейнера стандартной библиотеки или строковой функции-члена, могут обращаться к базовому контейнеру, но не должны его изменять. [ Note: В частности, операции контейнера, которые делают итераторы недействительными, конфликтуют с операциями над итераторами, связанными с этим контейнером. ] end note

Реализации могут совместно использовать свои внутренние объекты между потоками, если объекты не видны пользователям и защищены от скачков данных.

Если не указано иное, функции стандартной библиотеки C ++ должны выполнять все операции исключительно в текущем потоке, если эти операции оказывают влияние visible на пользователей.

[ Note: Это позволяет реализациям распараллеливать операции, если нет видимых побочных эффектов. ] end note

20.5.5.10 Protection within classes [protection.within.classes]

Не указано, является ли какая-либо сигнатура функции или класс, описанные в Разделах [language.support] по [thread] и Приложение [depr] , к friend другому классу в стандартной библиотеке C ++.

20.5.5.11 Derived classes [derivation]

Реализация может наследовать любой класс в стандартной библиотеке C ++ от класса с именем, зарезервированным для реализации.

Некоторые классы, определенные в стандартной библиотеке C ++, должны быть производными от других классов стандартной библиотеки C ++. Реализация может получить такой класс непосредственно из требуемой базы или косвенно через иерархию базовых классов с именами, зарезервированными для реализации.

В любом слючае:

  • Каждый базовый класс, описанный как, virtual должен быть виртуальным;

  • Каждый базовый класс, не указанный как virtual , не должен быть виртуальным;

  • Если явно не указано иное, типы с разными именами должны быть разными типами.182

Все типы, указанные в стандартной библиотеке C ++, не должны бытьfinal типами, если не указано иное.

Из этого правила есть неявное исключение для типов, которые описываются как синонимы для основных интегральных типов, таких как size_­t и streamoff.

20.5.5.12 Restrictions on exception handling [res.on.exception.handling]

Любая из функций, определенных в стандартной библиотеке C ++, может сообщать о сбое, генерируя исключение типа, описанного в его Throws: абзаце, или типа, производного от типа, названного в Throws: абзаце, которое будет перехвачено обработчиком исключений для базового типа. .

Функции из стандартной библиотеки C не должны вызывать исключения, 183 за исключением случаев, когда такая функция вызывает программную функцию, которая вызывает исключение.184

Операции деструктора, определенные в стандартной библиотеке C ++, не должны вызывать исключений. Каждый деструктор в стандартной библиотеке C ++ должен вести себя так, как если бы он имел спецификацию исключения, не вызывающего выброса.

Функции, определенные в стандартной библиотеке C ++, которые не имеют Throws: абзаца, но имеют спецификацию потенциально вызывающего исключения, могут вызывать исключения, определяемые реализацией.185 Реализации должны сообщать об ошибках, бросая исключения из или полученных из стандартных классов исключений ([bad.alloc], [support.exception], [std.exceptions]).

Реализация может усилить спецификацию исключения для невиртуальной функции, добавив спецификацию исключения исключения.

То есть все функции библиотеки C можно рассматривать так, как если бы они были отмечены noexcept. Это позволяет реализациям оптимизировать производительность на основе отсутствия исключений во время выполнения.

Функции qsort() и bsearch() ([alg.c.library]) удовлетворяют этому условию.

В частности, они могут сообщить об ошибке выделения хранилища, выбрасывая исключение типа bad_­allocили класса, производного от bad_­alloc.

20.5.5.13 Restrictions on storage of pointers [res.on.pointer.storage]

Объекты, созданные стандартной библиотекой, которые могут содержать значение указателя, предоставленное пользователем или целое число типа, std​::​intptr_­t должны хранить такие значения в файле traceable pointer location. [ Note: Другим библиотекам настоятельно рекомендуется делать то же самое, поскольку невыполнение этого может привести к случайному использованию указателей, которые не выводятся безопасно. Библиотеки, хранящие указатели вне адресного пространства пользователя, должны создавать впечатление, что они хранятся и извлекаются из отслеживаемого местоположения указателя. ] end note

20.5.5.14 Value of error codes [value.error.codes]

Некоторые функции стандартной библиотеки C ++ сообщают об ошибках через std​::​error_­code объект.category() Член этого объекта должен возвращать std​::​system_­category() для ошибок, происходящих из операционной системы, или ссылку на объект, определенный реализацией, error_­category для ошибок, возникающих в другом месте. Реализация должна определять возможные значения value() для каждой из этих категорий ошибок. [ Example: Для операционных систем, основанных на POSIX, реализациям рекомендуется определять std​::​system_­category() значения как идентичные errno значениям POSIX , с дополнительными значениями, как определено в документации операционной системы. Реализациям для операционных систем, не основанных на POSIX, рекомендуется определять значения, идентичные значениям операционной системы. Для ошибок, которые происходят не из операционной системы, реализация может предоставить перечисления для связанных значений. ] end example

20.5.5.15 Moved-from state of library types [lib.types.movedfrom]

Объекты типов, определенных в стандартной библиотеке C ++, можно перемещать из ([class.copy]). Операции перемещения могут быть заданы явно или неявно. Если не указано иное, такие перемещенные объекты должны быть переведены в допустимое, но неуказанное состояние.