26 Containers library [containers]

26.2 Container requirements [container.requirements]

26.2.1 General container requirements [container.requirements.general]

Контейнеры - это объекты, в которых хранятся другие объекты. Они контролируют выделение и освобождение этих объектов с помощью конструкторов, деструкторов, операций вставки и стирания.

Все требования к сложности в этом разделе указаны исключительно в терминах количества операций с содержащимися объектами. [ Example: Конструктор копирования типа vector<vector<int>> имеет линейную сложность, хотя сложность копирования каждого содержащегося в нем элемента vector<int> является линейной. ]end example

Для компонентов, затронутых этим подпунктом, которые объявляют allocator_­type, объекты, хранящиеся в этих компонентах, должны быть построены с использованием функции allocator_­traits<allocator_­type>​::​rebind_­traits<U>​::​​construct и уничтожены с помощью функции allocator_­traits<allocator_­type>​::​rebind_­traits<U>​::​​destroy, где U либо allocator_­type​::​value_­type внутренний тип, либо внутренний тип, используемый контейнером. Эти функции вызываются только для типа элемента контейнера, а не для внутренних типов, используемых контейнером. [ Note: Это означает, например, что контейнер на основе узлов может нуждаться в создании узлов, содержащих выровненные буферы, и вызове construct для помещения элемента в буфер. ]end note

В таблицах 83, 84и 85 X обозначает контейнерный класс, содержащий объекты типа T, a и b обозначают значения типа X, u обозначает идентификатор, r обозначает неконстантное значение типа Xи rv обозначает неконстантное rvalue типа X.

Таблица 83 - Требования к контейнерам
ВыражениеТип возвратаОперативныйУтверждение / примечаниеСложность
семантикадо / после состояния
X​::​value_­type T Requires:  T это Erasable от X (см [container.requirements.general], ниже) время компиляции
X​::​reference T& время компиляции
X​::​const_­reference const T& время компиляции
X​::​iterator тип итератора, тип значения которого T любая категория итераторов, отвечающая требованиям прямого итератора. конвертируемый в X​::​const_­iterator. время компиляции
X​::​const_­iterator постоянный тип итератора, тип значения которого T любая категория итераторов, отвечающая требованиям прямого итератора. время компиляции
X​::​difference_­type знаковый целочисленный тип идентичен типу разницы X​::​iterator и X​::​const_­iterator время компиляции
X​::​size_­type беззнаковый целочисленный тип size_­type может представлять любое неотрицательное значение difference_­type время компиляции
X u; Postconditions: u.empty() постоянный
X() Postconditions: X().empty() постоянный
X(a) Requires: T находится CopyInsertable в X (см. ниже).
Postconditions: a == X(a).
линейный
X u(a);
X u = a;
Requires: T находится CopyInsertable в X (см. ниже).
Postconditions: u == a
линейный
X u(rv);
X u = rv;
Postconditions: u будет равняться значению, которое rv имело до этого строительства (Примечание B)
a = rv X& Все существующие элементы a либо перемещаются, либо уничтожаются. a должно быть равно значению, которое rv имело до этого присвоения линейный
(&a)->~X() void деструктор применяется к каждому элементу a; любая полученная память освобождается. линейный
a.begin() iterator; const_­iterator для постоянного a постоянный
a.end() iterator; const_­iterator для постоянного a постоянный
a.cbegin() const_­iterator const_­cast<​X const&​>(a)​.begin(); постоянный
a.cend() const_­iterator const_­cast<​X const&​>(a)​.end(); постоянный
a == b конвертируемый в bool == является отношением эквивалентности. equal(​a.begin(), a.end(), b.begin(), b.end()) Requires:  T является EqualityComparable Постоянно, если a.size() != b.size(), линейно в противном случае
a != b конвертируемый в bool Эквивалентно !(a == b) линейный
a.swap(b) void обменивается содержимым a и b (Примечание А)
swap(a, b) void a.swap(b) (Примечание А)
r = a X& Postconditions: r == a. линейный
a.size() size_­type distance(​a.begin(), a.end()) постоянный
a.max_­size() size_­type distance(​begin(), end()) для максимально возможного контейнера постоянный
a.empty() конвертируемый в bool a.begin() == a.end() постоянный

Записи, отмеченные «(Примечание A)» или «(Примечание B)», имеют линейную сложность array и постоянную сложность для всех других стандартных контейнеров. [ Note: Алгоритм equal() определен в п [algorithms]. ]end note

Функция-член size() возвращает количество элементов в контейнере. Количество элементов определяется правилами конструкторов, вставок и стираний.

begin() возвращает итератор, ссылающийся на первый элемент в контейнере. end() возвращает итератор, который является последним значением для контейнера. Если емкость пуста, то begin() == end().

В выражениях

i == j
i != j
i < j
i <= j
i >= j
i > j
i - j

где i и j обозначают объекты типа контейнера iterator , один или оба могут быть заменены объектом типа контейнера, const_­iterator относящимся к тому же элементу без изменения семантики.

Если не указано иное, все контейнеры, определенные в этом пункте, получают память с помощью распределителя (см [allocator.requirements]. Раздел "Ресурсы" ). [ Note: В частности, контейнеры и итераторы не хранят ссылки на выделенные элементы, кроме как через тип указателя распределителя, то есть как объекты типа P или pointer_­traits<P>​::​template rebind<unspecified>, где P есть allocator_­traits<allocator_­type>​::​pointer. ] Конструкторы копирования для этих типов контейнеров получают распределитель, вызывая распределитель, принадлежащий копируемому контейнеру. Конструкторы перемещения получают распределитель, перемещая конструкцию из распределителя, принадлежащего перемещаемому контейнеру. Такая конструкция перемещения распределителя не должна завершаться через исключение. Все остальные конструкторы для этих типов контейнеров принимают аргумент. [ Если при вызове конструктора используется значение по умолчанию необязательного аргумента распределителя, то тип должен поддерживать инициализацию значения. ] Копия этого распределителя используется для любого выделения памяти и построения элементов, выполняемых этими конструкторами и всеми функциями-членами, в течение жизненного цикла каждого объекта-контейнера или до тех пор, пока распределитель не будет заменен. Распределитель может быть заменен только через присвоение или . Замена распределителя выполняется путем присваивания копии, присваивания перемещения или замены распределителя только в том случае , если , или находится в рамках реализации соответствующей операции контейнера. Во всех типах контейнеров, определенных в этом разделе, член возвращает копию распределителя, использованного для создания контейнера, или, если этот распределитель был заменен, копию самой последней замены. end noteallocator_­traits<allocator_­type>​::​select_­on_­container_­copy_­constructionconst allocator_­type& Note: Allocator end noteswap()allocator_­traits<allocator_­type>​::​propagate_­on_­container_­copy_­assignment​::​valueallocator_­traits<allocator_­type>​::​propagate_­on_­container_­move_­assignment​::​value allocator_­traits<allocator_­type>​::​propagate_­on_­container_­swap​::​value true get_­allocator()

Выражение a.swap(b)для контейнеров a и b стандартного типа контейнера, отличного от array, должно обмениваться значениями a и b без вызова каких-либо операций перемещения, копирования или обмена для отдельных элементов контейнера. L-значения любого Compare, Predили Hash типов, принадлежащих a и b должны быть взаимозаменяемыми и должны быть обменены путем вызова, swap как описано в [swappable.requirements]. Если allocator_­traits<allocator_­type>​::​propagate_­on_­container_­swap​::​value есть true, то lvalues ​​типа allocator_­type должны быть заменены , а распределители a и b также должны обмениваться посредством вызова, swap как описано в [swappable.requirements]. В противном случае распределители не должны меняться местами, и поведение не определено, если только a.get_­allocator() == b.get_­allocator(). Каждый итератор, ссылающийся на элемент в одном контейнере до обмена, должен ссылаться на тот же элемент в другом контейнере после обмена. Не указано, будет ли итератор со значением a.end() до обмена иметь значение b.end() после обмена.

Если тип итератора контейнера принадлежит к двунаправленному или произвольному доступу iterator categories, контейнер вызывается reversible и удовлетворяет дополнительным требованиям в таблице 84.

Таблица 84 - Требования к двусторонним контейнерам
ВыражениеТип возвратаУтверждение / примечаниеСложность
до / после состояния
X​::​reverse_­iterator тип итератора, тип значения которого T reverse_­iterator<iterator> время компиляции
X​::​const_­reverse_­iterator постоянный тип итератора, тип значения которого T reverse_­iterator<const_­iterator> время компиляции
a.rbegin() reverse_­iterator; const_­reverse_­iterator для постоянного a reverse_­iterator(end()) постоянный
a.rend() reverse_­iterator; const_­reverse_­iterator для постоянного a reverse_­iterator(begin()) постоянный
a.crbegin() const_­reverse_­iterator const_­cast<X const&>(a).rbegin() постоянный
a.crend() const_­reverse_­iterator const_­cast<X const&>(a).rend() постоянный

Если не указано иное (см [associative.reqmts.except], [unord.req.except], [deque.modifiers], и [vector.modifiers]) все типы контейнеров определено в настоящем пункте встречаются следующие дополнительные требования:

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

  • если исключение брошенное push_­back(), push_­front(), emplace_­back()или emplace_­front() функция, что функция не имеет никакого эффекта.

  • нет erase(), clear(), pop_­back() или pop_­front() функция вызывает исключение.

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

  • ни одна swap() функция не вызывает исключение.

  • никакая swap() функция не делает недействительными любые ссылки, указатели или итераторы, относящиеся к элементам заменяемых контейнеров. [ Итератора не относится к любому элементу, так что она может быть признана недействительной. ] Note: end() end note

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

A contiguous container - это контейнер, который поддерживает random access iterators и чьи типы членов iterator и const_­iterator являются contiguous iterators.

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

Таблица 85 - Необязательные контейнерные операции
ВыражениеТип возвратаОперативныйУтверждение / примечаниеСложность
семантикадо / после состояния
a < b конвертируемый в bool lexicographical_­compare( a.begin(), a.end(), b.begin(), b.end()) Requires: < определяется для значений T. < это отношения полного порядка. линейный
a > b конвертируемый в bool b < a линейный
a <= b конвертируемый в bool !(a > b) линейный
a >= b конвертируемый в bool !(a < b) линейный

[ Note: Алгоритм lexicographical_­compare() определен в п [algorithms]. ]end note

Все контейнеры, определенные в этом разделе и за [basic.string] исключением, array соответствуют дополнительным требованиям к контейнеру, поддерживающему распределитель, как описано в таблице 86.

Для данного типа распределителя A и данного типа контейнера, X имеющего value_­type идентичный T и allocator_­type идентичный, allocator_­traits<A>​::​rebind_­alloc<T> и заданного lvalue m типа A, указателя p типа T*, выражения v типа (возможно const) Tи rvalue rv типа T, определены следующие термины. Если X не известно о распределителе, приведенные ниже термины определены как если бы A были allocator<T> - не нужно создавать объект распределителя и allocator<T> не создавать экземпляры пользовательских специализаций :

  • T это DefaultInsertable into X означает , что следующее выражение хорошо сформировано:

    allocator_traits<A>::construct(m, p)
  • Элемент X is, default-inserted если он инициализируется вычислением выражения

    allocator_traits<A>::construct(m, p)

    где p - адрес неинициализированного хранилища для выделенного внутри элемента X.

  • T это MoveInsertable into X означает , что следующее выражение хорошо сформировано:

    allocator_traits<A>::construct(m, p, rv)

    и его оценка вызывает выполнение следующего постусловия: значение *p эквивалентно значению rv до оценки. [ Note: rv остается действующим объектом. Его состояние не указано ] end note

  • T это CopyInsertable into X означает , что, в дополнение к T быть MoveInsertable в Xследующее выражение хорошо сформированы:

    allocator_traits<A>::construct(m, p, v)

    и его оценка вызывает выполнение следующего постусловия: значение v не изменяется и эквивалентно *p.

  • T это EmplaceConstructible into X from args, ноль или более аргументов args, означает , что следующее выражение хорошо сформированные:

    allocator_traits<A>::construct(m, p, args)
  • T это Erasable from X означает , что следующее выражение хорошо сформировано:

    allocator_traits<A>::destroy(m, p)

[ Note: Контейнер вызывает allocator_­traits<A>​::​construct(m, p, args) создание элемента при p использовании args, with m == get_­allocator(). По умолчанию construct in allocator будет вызывать ​::​new((void*)p) T(args), но специализированные распределители могут выбрать другое определение. ]end note

В таблице 86, X обозначает распределитель-Aware класса контейнера с value_­type из T помощью аллокатора типа A, u обозначает переменный, a и b обозначает неконстантную lvalues типа X, t обозначает именующее выражение или константный RValue типа X, rv обозначает неконстантную RValue типа X, и m является значением типа A.

Таблица 86 - Требования к контейнерам с учетом распределителя
ВыражениеТип возвратаУтверждение / примечаниеСложность
до / после состояния
allocator_­type A Requires: allocator_­type​::​value_­type то же самое, что и X​::​value_­type. время компиляции
get_­- allocator() A постоянный
X()
X u;
Requires:  A есть DefaultConstructible.
Postconditions: u.empty() возвращается true, u.get_­allocator() == A()
постоянный
X(m) Postconditions: u.empty() возвращается true, постоянный
X u(m); u.get_­allocator() == m
X(t, m)
X u(t, m);
Requires:  T находится CopyInsertable в X.
Postconditions: u == t, u.get_­allocator() == m
линейный
X(rv)
X u(rv);
Postconditions: u должен иметь те же элементы, что rv и до этого строительства; значение u.get_­allocator() должно быть таким же, как значение rv.get_­allocator() до этого строительства. постоянный
X(rv, m)
X u(rv, m);
Requires:  T находится MoveInsertable в X.
Postconditions: u должны иметь те же элементы или копии элементов, которые rv были до этого строительства, u.get_­allocator() == m
постоянная, если m == rv.get_­allocator(), в противном случае линейная
a = t X& Requires:  T находится CopyInsertable в X и CopyAssignable.
Postconditions: a == t
линейный
a = rv X& Requires:  Если есть , это в и . Все существующие элементы либо передаются, либо уничтожаются. будет равно значению, которое имело до этого присвоения. allocator_­-
traits<allocator_­type>
​::​propagate_­on_­container_­-
move_­assignment​::​value
false T MoveInsertable X MoveAssignable a
Postconditions: a rv
линейный
a.swap(b) void обменивается содержимым a и b постоянный

Поведение определенных функций-членов контейнера и руководств по выводам зависит от того, квалифицируются ли типы как итераторы ввода или распределители. Степень, в которой реализация определяет, что тип не может быть итератором ввода, не определена, за исключением того, что как минимум целочисленные типы не должны квалифицироваться как итераторы ввода. Аналогично, степень, в которой реализация определяет, что тип не может быть распределителем, не указана, за исключением того, что, как минимум, тип A не должен считаться распределителем, если он не удовлетворяет обоим из следующих условий:

  • qualified-id A​::​value_­type Является действительным , и обозначает тип ([temp.deduct]).

  • Выражение declval<A&>().allocate(size_­t{}) правильно сформировано, когда рассматривается как неоцененный операнд.

26.2.2 Container data races [container.requirements.dataraces]

Для целей avoiding data races, реализации должны учитывать следующие функции будут const: begin, end, rbegin, rend, front, back, data, find, lower_­bound, upper_­bound, equal_­range, at и, кроме ассоциативных или неупорядоченных ассоциативных контейнеров operator[].

Тем не менее [res.on.data.races], реализации требуются, чтобы избежать гонки за данными, когда содержимое содержащегося объекта в разных элементах в одном и том же контейнере, за исключением vector<bool>, изменяется одновременно.

[ Note: Для a vector<int> x с размером больше единицы x[1] = 5 и *x.begin() = 10 может выполняться одновременно без гонки данных, но x[0] = 5 и *x.begin() = 10 выполняться одновременно может привести к гонке данных. В качестве исключения из общего правила, для vector<bool> y, y[0] = true может мчаться с y[1] = true. ]end note

26.2.3 Sequence containers [sequence.reqmts]

Контейнер последовательности организует конечный набор объектов одного типа в строго линейную структуру. Библиотека обеспечивает четыре основных видов контейнеров последовательности: vector, forward_­list, list, и deque. Кроме того, array предоставляется как контейнер последовательности, который обеспечивает ограниченные операции последовательности, поскольку он имеет фиксированное количество элементов. Библиотека также предоставляет адаптеры контейнеров, которые упрощают создание абстрактных типов данных, таких как stacks или queues, из основных типов контейнеров последовательностей (или из других типов контейнеров последовательностей, которые может определить пользователь).

Контейнеры последовательностей предлагают программисту различные компромиссы сложности и должны использоваться соответственно. vector или array - это тип контейнера последовательности, который следует использовать по умолчанию. list или forward_­list должен использоваться, когда есть частые вставки и удаления из середины последовательности. deque - это предпочтительная структура данных, когда большинство вставок и удалений происходит в начале или в конце последовательности.

В таблицах 87 и 88, X обозначает класс контейнера последовательности, a обозначает значение типа , X содержащего элементы типа T, u обозначает имя переменной объявляется, A означает , X​::​allocator_­type если qualified-id X​::​allocator_­type является действительным , и обозначает тип ([temp.deduct]) , а allocator<T> не тогда , когда это произойдет, i и j обозначают итераторы удовлетворение требований входного итератора и ссылка на элементы, неявно конвертируемые в value_­type, [i, j) обозначает допустимый диапазон, il обозначает объект типа initializer_­list<value_­type>, n обозначает значение типа X​::​size_­type, p обозначает допустимый итератор константы для a, q обозначает допустимый разыменовываемый итератор константы a, [q1, q2) обозначает допустимый диапазон констант итераторы в a, t обозначает lvalue или const rvalue для X​::​value_­typeи rv обозначает неконстантное rvalue для X​::​value_­type. Args обозначает пакет параметров шаблона; args обозначает пакет параметров функции с шаблоном Args&&.

Сложность выражений зависит от последовательности.

Таблица 87 - Требования к контейнеру последовательности (в дополнение к контейнеру)
ВыражениеТип возвратаУтверждение / примечание
до / после состояния
X(n, t)
X u(n, t);
Requires:  T должен быть CopyInsertable в X. Создает контейнер последовательности с копиями
Postconditions: distance(begin(), end()) == n
n t
X(i, j)
X u(i, j);
Requires:  T должен быть EmplaceConstructible в X от *i. Ибо vector, если итератор не соответствует forward iterator requirements, T также должен быть MoveInsertable включен X. Каждый итератор в диапазоне [i, j) должен быть разыменован ровно один раз. Создает контейнер последовательности, равный диапазону
Postconditions: distance(begin(), end()) == distance(i, j)
[i, j)
X(il) Эквивалентно X(il.begin(), il.end())
a = il X& Requires:  T находится CopyInsertable в X и CopyAssignable. Назначает диапазон [il.begin(), il.end()) в a. Все существующие элементы a либо присваиваются, либо уничтожаются.
Returns:  *this.
a.emplace(p, args) iterator Requires:  T находится EmplaceConstructible в X от args. Для vector и deque, T также MoveInsertable в X и MoveAssignable. Effects:  Вставляет объект типа, созданного T с помощью std​::​forward<​Args​>(​args)... before p.
a.insert(p,t) iterator Requires:  T должен быть CopyInsertable в X. Для vector и deque, T также должно быть CopyAssignable.
Effects:  Вставляет копию t ранее p.
a.insert(p,rv) iterator Requires:  T должен быть MoveInsertable в X. Для vector и deque, T также должно быть MoveAssignable.
Effects:  Вставляет копию rv ранее p.
a.insert(p,n,t) iterator Requires:  T должны быть CopyInsertable в X и CopyAssignable.
Вставляет n копии t ранее p.
a.insert(p,i,j) iterator Requires:  T должен быть EmplaceConstructible в X от *i. Для vector и deque, T должен также быть MoveInsertable в X, MoveConstructible, MoveAssignable, и swappable. Каждый итератор в диапазоне [i, j) должен быть разыменован ровно один раз.
Requires: i и j не являются итераторами a.
Вставляет копии элементов [i, j) перед p
a.insert(p, il) iterator a.insert(p, il.begin(), il.end()).
a.erase(q) iterator Requires:  Для vector и deque, T должно быть MoveAssignable.
Effects:  Удаляет элемент, на который указывает q.
a.erase(q1,q2) iterator Requires:  Для vector и deque, T должно быть MoveAssignable.
Effects:  Стирает элементы в диапазоне [q1, q2).
a.clear() void Уничтожает все элементы в a. Делает недействительными все ссылки, указатели и итераторы, относящиеся к элементам, a и может сделать недействительным итератор, прошедший за конец.
Postconditions: a.empty() возвращается true.
Complexity: Линейный.
a.assign(i,j) void Requires:  T должно быть EmplaceConstructible в X от *i и может быть назначено от *i. Ибо vector, если итератор не соответствует forward iterator requirements, T также должен быть MoveInsertable включен X.
Каждый итератор в диапазоне [i, j) должен быть разыменован ровно один раз.
Requires: i, j не являются итераторами в a.
Заменяет элементы в a копии [i, j).
Делает недействительными все ссылки, указатели и итераторы, относящиеся к элементам a. Для vector и dequeтакже делает недействительным итератор, прошедший за конец.
a.assign(il) void a.assign(il.begin(), il.end()).
a.assign(n,t) void Requires:  T должны быть CopyInsertable в X и CopyAssignable.
Requires: t это не ссылка на a.
Заменяет элементы a с n копиями t.
Делает недействительными все ссылки, указатели и итераторы, относящиеся к элементам a. Для vector и dequeтакже делает недействительным итератор, прошедший за конец.

Итератор вернулся из a.insert(p, t) точек в копию, t вставленную в a.

Итератор вернулся из a.insert(p, rv) точек в копию, rv вставленную в a.

Итератор вернулся из a.insert(p, n, t) точек в копию первого вставленного элемента a, или p if n == 0.

Итератор вернулся из a.insert(p, i, j) точек в копию первого вставленного элемента a, или p if i == j.

Итератор вернулся из a.insert(p, il) точек в копию первого вставленного элемента aили p если il он пуст.

Итератор вернулся из a.emplace(p, args) точек в новый элемент, созданный из args в a.

Итератор вернулся из a.erase(q) точек в элемент, следующий непосредственно за q стираемым элементом. Если такого элемента не существует, a.end() возвращается.

Итератор, возвращаемый a.erase(q1, q2) точкой, указывает элемент, на который указывает q2 до того, как какие-либо элементы будут удалены. Если такого элемента не существует, a.end() возвращается.

Для каждого контейнера последовательности, определенного в этом Пункте и Пункте [strings]:

  • Если конструктор

    template <class InputIterator>
      X(InputIterator first, InputIterator last,
        const allocator_type& alloc = allocator_type());

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

  • Если функции-члены форм:

    template <class InputIterator>
      return-type F(const_iterator p,
                    InputIterator first, InputIterator last);       // such as insert
    
    template <class InputIterator>
      return-type F(InputIterator first, InputIterator last);       // such as append, assign
    
    template <class InputIterator>
      return-type F(const_iterator i1, const_iterator i2,
                    InputIterator first, InputIterator last);       // such as replace
    

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

  • Руководство по дедукции для контейнера последовательности не должно участвовать в разрешении перегрузки, если у него есть InputIterator параметр шаблона и для этого параметра выводится тип, который не квалифицируется как итератор ввода, или если у него есть Allocator параметр шаблона и тип, который не соответствует требованиям. как распределитель для этого параметра.

В таблице 88 перечислены операции, которые предусмотрены для одних типов контейнеров последовательностей, но не для других. Реализация должна обеспечивать эти операции для всех типов контейнеров, показанных в столбце «контейнер», и должна реализовывать их так, чтобы использовать амортизированное постоянное время.

Таблица 88 - Операции контейнера необязательной последовательности
ВыражениеТип возвратаОперационная семантикаКонтейнер
a.front() reference; const_­reference для постоянного a *a.begin() basic_­string, array, deque, forward_­list, list, vector
a.back() reference; const_­reference для постоянного a { auto tmp = a.end();
--tmp;
return *tmp; }
basic_­string, array, deque, list, vector
a.emplace_­front(args) reference Добавляет объект типа, созданный T с помощью std​::​forward<​Args​>(​args)....
Requires:  T должен быть EmplaceConstructible в X от args.
Returns: a.front().
deque, forward_­list, list
a.emplace_­back(args) reference Добавляет объект типа, созданного T с помощью std​::​forward<​Args​>(​args)....
Requires:  T должен быть EmplaceConstructible в X от args. Для vector, T также должны быть MoveInsertable в X.
Returns: a.back().
deque, list, vector
a.push_­front(t) void Готовит копию t.
Requires:  T должен быть CopyInsertable в X.
deque, forward_­list, list
a.push_­front(rv) void Готовит копию rv.
Requires:  T должен быть MoveInsertable в X.
deque, forward_­list, list
a.push_­back(t) void Добавляет копию t.
Requires:  T должен быть CopyInsertable в X.
basic_­string, deque, list, vector
a.push_­back(rv) void Добавляет копию rv.
Requires:  T должен быть MoveInsertable в X.
basic_­string, deque, list, vector
a.pop_­front() void Уничтожает первый элемент.
Requires:  a.empty() будет false.
deque, forward_­list, list
a.pop_­back() void Уничтожает последний элемент.
Requires:  a.empty() будет false.
basic_­string, deque, list, vector
a[n] reference; const_­reference для постоянного a *(a.begin() + n) basic_­string, array, deque, vector
a.at(n) reference; const_­reference для постоянного a *(a.begin() + n) basic_­string, array, deque, vector

Функция-член at() обеспечивает доступ к элементам контейнера с проверкой границ. at() кидает out_­of_­range если n >= a.size().

26.2.4 Node handles [container.node]

26.2.4.1 node_­handle overview [container.node.overview]

A node handle - это объект, который принимает владение одним элементом из associative container или unordered associative container. Его можно использовать для передачи этого владения другому контейнеру с совместимыми узлами. Контейнеры с совместимыми узлами имеют одинаковый тип дескриптора узла. Элементы могут передаваться в любом направлении между типами контейнеров в одной строке таблицы 89.

Таблица 89 - Типы контейнеров с совместимыми узлами
map<K, T, C1, A> map<K, T, C2, A>
map<K, T, C1, A> multimap<K, T, C2, A>
set<K, C1, A> set<K, C2, A>
set<K, C1, A> multiset<K, C2, A>
unordered_­map<K, T, H1, E1, A> unordered_­map<K, T, H2, E2, A>
unordered_­map<K, T, H1, E1, A> unordered_­multimap<K, T, H2, E2, A>
unordered_­set<K, H1, E1, A> unordered_­set<K, H2, E2, A>
unordered_­set<K, H1, E1, A> unordered_­multiset<K, H2, E2, A>

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

Класс node_­handle предназначен только для экспозиции. Реализации разрешено предоставлять эквивалентную функциональность без предоставления класса с этим именем.

Если определенная пользователем специализация pair существует для pair<const Key, T> или pair<Key, T>, где Key - контейнер, key_­type а T - контейнер mapped_­type, поведение операций, связанных с дескрипторами узлов, не определено.

template<unspecified>
  class node_handle {
  public:
    // These type declarations are described in Tables 90 and 91.
    using value_type     = see below;   // not present for map containers
    using key_type       = see below;   // not present for set containers
    using mapped_type    = see below;   // not present for set containers
    using allocator_type = see below;

  private:
    using container_node_type = unspecified;
    using ator_traits = allocator_traits<allocator_type>;

    typename ator_traits::rebind_traits<container_node_type>::pointer ptr_;
    optional<allocator_type> alloc_;

  public:
    constexpr node_handle() noexcept : ptr_(), alloc_() {}
    ~node_handle();
    node_handle(node_handle&&) noexcept;
    node_handle& operator=(node_handle&&);

    value_type& value() const;          // not present for map containers
    key_type& key() const;              // not present for set containers
    mapped_type& mapped() const;        // not present for set containers

    allocator_type get_allocator() const;
    explicit operator bool() const noexcept;
    bool empty() const noexcept;

    void swap(node_handle&)
      noexcept(ator_traits::propagate_on_container_swap::value ||
               ator_traits::is_always_equal::value);

    friend void swap(node_handle& x, node_handle& y) noexcept(noexcept(x.swap(y))) {
      x.swap(y);
    }
};

26.2.4.2 node_­handle constructors, copy, and assignment [container.node.cons]

node_handle(node_handle&& nh) noexcept;

Effects: Создает node_­handle объект, инициализируемый ptr_­ с помощью nh.ptr_­. Перемещайте конструкции alloc_­ с помощью nh.alloc_­. Назначает nullptr к nh.ptr_­ и правопреемникам nullopt к nh.alloc_­.

node_handle& operator=(node_handle&& nh);

Requires: Либо !alloc_­, либо ator_­traits​::​propagate_­on_­container_­move_­assignment есть true, либо alloc_­ == nh.alloc_­.

Effects:

  • Если ptr_­ != nullptrуничтожает value_­type подобъект в container_­node_­type объекте, на который указывает ptr_­ вызов ator_­traits​::​destroy, затем освобождает его ptr_­ путем вызова ator_­traits​::​rebind_­traits<container_­node_­type>​::​deallocate.

  • Назначает nh.ptr_­ в ptr_­.

  • Если !alloc_ или ator_­traits​::​propagate_­on_­container_­move_­assignment есть true, move назначает nh.alloc_­ на alloc_­.

  • Назначает nullptr к nh.ptr_­ и правопреемникам nullopt к nh.alloc_­.

Returns: *this.

Throws: Ничего такого.

26.2.4.3 node_­handle destructor [container.node.dtor]

~node_handle();

Effects: Если ptr_­ != nullptrуничтожает value_­type подобъект в container_­node_­type объекте, на который указывает ptr_­ вызов ator_­traits​::​destroy, затем освобождает его ptr_­ путем вызова ator_­traits​::​rebind_­traits<container_­node_­type>​::​deallocate.

26.2.4.4 node_­handle observers [container.node.observers]

value_type& value() const;

Requires: empty() == false.

Returns: Ссылка на value_­type подобъект в container_­node_­type объекте, на который указывает ptr_­.

Throws: Ничего такого.

key_type& key() const;

Requires: empty() == false.

Returns: Неконстантная ссылка на key_­type член value_­type подобъекта в container_­node_­type объекте, на который указывает ptr_­.

Throws: Ничего такого.

Remarks: Разрешено изменение ключа с помощью возвращенной ссылки.

mapped_type& mapped() const;

Requires: empty() == false.

Returns: Ссылка на mapped_­type член value_­type подобъекта в container_­node_­type объекте, на который указывает ptr_­.

Throws: Ничего такого.

allocator_type get_allocator() const;

Requires: empty() == false.

Returns: *alloc_­.

Throws: Ничего такого.

explicit operator bool() const noexcept;

Returns: ptr_­ != nullptr.

bool empty() const noexcept;

Returns: ptr_­ == nullptr.

26.2.4.5 node_­handle modifiers [container.node.modifiers]

void swap(node_handle& nh) noexcept(ator_traits::propagate_on_container_swap::value || ator_traits::is_always_equal::value);

Requires: !alloc_­, или !nh.alloc_­, или ator_­traits​::​propagate_­on_­container_­swap есть true, или alloc_­ == nh.alloc_­.

Effects: Звонки swap(ptr_­, nh.ptr_­). Если !alloc_­, или !nh.alloc_­, или ator_­traits​::​propagate_­on_­container_­swap это true звонки swap(alloc_­, nh.alloc_­).

26.2.5 Insert return type [container.insert.return]

Ассоциативные контейнеры с уникальными ключами и неупорядоченные контейнеры с уникальными ключами имеют функцию-член, insert которая возвращает вложенный тип insert_­return_­type. Этот возвращаемый тип является специализацией типа, указанного в этом подпункте.

template <class Iterator, class NodeType>
struct INSERT_RETURN_TYPE
{
  Iterator position;
  bool     inserted;
  NodeType node;
};

Название INSERT_­RETURN_­TYPE только экспозиция. INSERT_­RETURN_­TYPE имеет параметры шаблона, элементы данных и специальные элементы, указанные выше. У него нет других базовых классов или членов, кроме указанных.

26.2.6 Associative containers [associative.reqmts]

Ассоциативные контейнеры обеспечивают быстрый поиск данных на основе ключей. Библиотека обеспечивает четыре основных вида ассоциативных контейнеров: set, multiset, map и multimap.

Каждый ассоциативный контейнер параметризован Key и имеет отношение упорядочения, Compare которое индуцирует a strict weak ordering на элементах Key. Кроме того, map и multimap связать произвольный файл mapped type T с расширениемKey. Объект типа Compare называется comparison object контейнером.

Фраза «эквивалентность ключей» означает отношение эквивалентности, налагаемое сравнением и not включением operator== ключей. То есть, два ключа k1 и k2 считаются эквивалентными , если для объекта сравнения comp, comp(k1, k2) == false && comp(k2, k1) == false. Для любых двух ключей k1 и k2 в том же контейнере, вызывающий comp(k1, k2) должен всегда возвращает то же значение.

Ассоциативный контейнер поддерживает, unique keys если он может содержать не более одного элемента для каждого ключа. В противном случае поддерживает equivalent keys. set И map классы поддерживают уникальные ключи; multiset и multimap классы поддержки эквивалентных ключей. Для multiset и multimap, insert, emplaceи erase сохранить относительный порядок эквивалентных элементов.

Для set и multiset тип значения совпадает с типом ключа. Ибо map и multimap он равен pair<const Key, T>.

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

Ассоциативные контейнеры соответствуют всем требованиям Allocator-aware контейнеров, за исключением map и multimap, требования, указанные value_­type в таблице, 83 применяются вместо key_­type и mapped_­type. [ Note: Например, в некоторых случаях key_­type и mapped_­type требуется, чтобы он был, CopyAssignable даже если связанный value_­type, pair<const key_­type, mapped_­type>не является CopyAssignable. ] end note

В таблице 90, X обозначает ассоциативный класс контейнера, a обозначает значение типа X, a2 обозначает значение типа с узлами , совместимыми с типом X (таблица 89), b обозначает возможно , const значение типа X, u обозначает имя переменного объявляется, a_­uniq обозначает значение type, X когда X поддерживает уникальные ключи, a_­eq обозначает значение типа, X когда X поддерживает несколько ключей, a_­tran обозначает возможное const значение типа, X когда qualified-id X​::​key_­compare​::​is_­transparent является допустимым, и обозначает тип ([temp.deduct]), i и j удовлетворяет требованиям входного итератора и ссылается на элементы, неявно конвертируемые в value_­type, [i, j) обозначает допустимый диапазон , p обозначает допустимый итератор константы для a, q обозначает действительный итератор константы, для которого разыменовывается a, r обозначает действительный итератор, допускающий разыменование a, [q1, q2) обозначает допустимый диапазон итераторов констант в a, il обозначает объект типа initializer_­list<value_­type>, t обозначает значение типа X​::​value_­type, k обозначает значение типа X​::​key_­type и c обозначает возможное const значение типа X​::​key_­compare; kl это значение таким образом, что a это partitioned with respect to c(r, kl), с r ключевым значением , e и e в a; ku - такое значение, которое a разделено относительно !c(ku, r); ke - это такое значение, которое a разделено относительно c(r, ke) и !c(ke, r), с c(r, ke) подразумеваемым !c(ke, r). A обозначает распределитель памяти, используемый X, если он есть, или allocator<X​::​value_­type> иначе, m обозначает распределитель типа, в который можно преобразовать A, и nh обозначает неконстантное rvalue типа X​::​node_­type.

Таблица 90 - Требования к ассоциативному контейнеру (в дополнение к контейнеру)
ВыражениеТип возвратаУтверждение / примечаниеСложность
до / после состояния
X​::​key_­type Key время компиляции
X​::​mapped_­type (map и multimap только) T время компиляции
X​::​value_­type (set и multiset только) Key Requires:  value_­type это Erasable из X время компиляции
X​::​value_­type (map и multimap только) pair<const Key, T> Requires:  value_­type это Erasable из X время компиляции
X​::​key_­compare Compare Requires:  key_­compare есть CopyConstructible. время компиляции
X​::​value_­compare бинарный тип предиката то же самое, что и key_­compare для set и multiset; является отношением порядка на парах, индуцированным первой компонентой (т. е. Key) для map и multimap. время компиляции
X​::​node_­type специализация node_­handle шаблона класса, так что общедоступные вложенные типы являются теми же типами, что и соответствующие типы в X. видеть [container.node] время компиляции
X(c)
X u(c);
Effects:  Создает пустой контейнер. Использует копию c как объект сравнения. постоянный
X()
X u;
Requires:  key_­compare есть DefaultConstructible.
Effects:  Создает пустой контейнер. Используется Compare() как объект сравнения
постоянный
X(i,j,c)
X u(i,j,c);
Requires:  value_­type находится EmplaceConstructible в X от *i.
Effects:  Создает пустой контейнер и вставляет в него элементы из диапазона [i, j) ; используется c как объект сравнения.
NlogN в общем, где N имеет значение distance(i, j); линейный, если [i, j) отсортировано с помощью value_­comp()
X(i,j)
X u(i,j);
Requires:  key_­compare есть DefaultConstructible. value_­type находится EmplaceConstructible в X от *i.
Effects:  То же, что и выше, но используется Compare() как объект сравнения.
то же, что и выше
X(il) такой же как X(il.begin(), il.end()) такой же как X(il.begin(), il.end())
X(il,c) такой же как X(il.begin(), il.end(), c) такой же как X(il.begin(), il.end(), c)
a = il X& Requires:  value_­type находится CopyInsertable в X и CopyAssignable.
Effects: Назначает диапазон [il.begin(), il.end()) в a. Все существующие элементы a либо присваиваются, либо уничтожаются.
NlogN в общем, где N имеет значение il.size() + a.size(); линейный, если [il.begin(), il.end()) отсортировано с помощью value_­comp()
b.key_­comp() X​::​key_­compare возвращает объект сравнения, из которого b был построен. постоянный
b.value_­comp() X​::​value_­compare возвращает объект, value_­compare созданный из объекта сравнения постоянный
a_­uniq.​emplace(​args) pair<​iterator, bool> Requires:  value_­type должен быть EmplaceConstructible в X от args.
Effects:  Вставляет value_­type объект, t созданный с помощью std​::​forward<​Args​>(​args)... if и только если в контейнере нет элемента с ключом, эквивалентным ключу t. bool Компонент возвращаемой пары true тогда и только тогда , когда имеет место вставка, а итератор компонент из точек пары к элементу с ключом , эквивалентным ключом t.
логарифмический
a_­eq.​emplace(​args) iterator Requires:  value_­type должен быть EmplaceConstructible в X от args.
Effects:  Вставляет value_­type объект, созданный t с помощью, std​::​forward<​Args​>(​args)... и возвращает итератор, указывающий на вновь вставленный элемент. Если диапазон, содержащий элементы, эквивалентные t существующим в a_­eq, t вставляется в конец этого диапазона.
логарифмический
a.emplace_­hint(​p, args) iterator эквивалентно a.emplace( std​::​forward<​Args​>(​args)...). Возвращаемое значение - это итератор, указывающий на элемент с ключом, эквивалентным вновь вставленному элементу. Элемент вставляется как можно ближе к позиции непосредственно перед p. логарифмическая в целом, но амортизированная константа, если элемент вставлен прямо перед p
a_­uniq.​insert(​t) pair<​iterator, bool> Requires:  Если t - неконстантное выражение rvalue, value_­type должно быть MoveInsertable в X; в противном случае value_­type будет CopyInsertable в X.
Effects:  Вставляет t тогда и только тогда, когда в контейнере нет элемента с ключом, эквивалентным ключу t. bool Компонент возвращаемой пары true тогда и только тогда , когда имеет место вставки, и iterator компонент точек пары к элементу с ключом , эквивалентным ключом t.
логарифмический
a_­eq.​insert(​t) iterator Requires:  Если t - неконстантное выражение rvalue, value_­type должно быть MoveInsertable в X; в противном случае value_­type будет CopyInsertable в X.
Effects:  Вставляет t и возвращает итератор, указывающий на вновь вставленный элемент. Если диапазон, содержащий элементы, эквивалентные t существующим в a_­eq, t вставляется в конец этого диапазона.
логарифмический
a.​insert(​p, t) iterator Requires:  Если t - неконстантное выражение rvalue, value_­type должно быть MoveInsertable в X; в противном случае value_­type будет CopyInsertable в X.
Effects:  Вставляет, t если и только если нет элемента с ключом, эквивалентным ключу t в контейнерах с уникальными ключами; всегда вставляет t в контейнеры с эквивалентными ключами. Всегда возвращает итератор, указывающий на элемент с ключом, эквивалентным ключу t. t вставляется как можно ближе к позиции непосредственно перед p.
логарифмическая в целом, но амортизированная константа, если t вставлена ​​прямо перед ней p.
a.​insert(​i, j) void Requires:  value_­type должен быть EmplaceConstructible в X от *i.
Requires: i, j не являются итераторами в a. вставляет каждый элемент из диапазона [i, j) тогда и только тогда, когда нет элемента с ключом, эквивалентным ключу этого элемента, в контейнерах с уникальными ключами; всегда вставляет этот элемент в контейнеры с эквивалентными ключами.
Nlog(a.size()+N), где N имеет значение distance(i, j)
a.​insert(​il) void эквивалентно a.insert(il.begin(), il.end())
a_­uniq.​insert(​nh) insert_­return_­type Requires: nh пусто или a_­uniq.get_­allocator() == nh.get_­allocator().
Effects: Если nh пусто, не действует. В противном случае вставляет элемент, владельцем которого является, nh тогда и только тогда, когда в контейнере нет элемента с ключом, эквивалентным nh.key().
Postconditions: Если nh пусто, inserted есть false, position есть end()и node пусто. В противном случае, если вставка имела место, inserted is true, position указывает на вставленный элемент и node является пустым; если вставка не удалась, inserted это false, node имеет предыдущее значение nh, и position указывает на элемент с ключом , эквивалентным nh.key().
логарифмический
a_­eq.​insert(​nh) iterator Requires: nh пусто или a_­eq.get_­allocator() == nh.get_­allocator().
Effects: Если nh пусто, не действует и возвращается a_­eq.end(). В противном случае вставляет элемент, которым владеет, nh и возвращает итератор, указывающий на вновь вставленный элемент. Если диапазон, содержащий элементы с ключами, эквивалентными, nh.key() существует в a_­eq, элемент вставляется в конец этого диапазона.
Postconditions: nh пустой.
логарифмический
a.​insert(​p, nh) iterator Requires: nh пусто или a.get_­allocator() == nh.get_­allocator().
Effects: Если nh пусто, не действует и возвращается a.end(). В противном случае вставляет элемент, принадлежащий пользователю nh тогда и только тогда, когда нет элемента с ключом, эквивалентным nh.key() в контейнерах с уникальными ключами; всегда вставляет элемент, которым владеет, nh в контейнеры с эквивалентными ключами. Всегда возвращает итератор, указывающий на элемент с ключом, эквивалентным nh.key(). Элемент вставляется как можно ближе к позиции непосредственно перед p.
Postconditions: nh пусто, если вставка прошла успешно, не изменяется, если вставка не удалась.
логарифмическая в общем случае, но амортизированная константа, если элемент вставлен прямо перед ним p.
a.​extract(​k) node_­type удаляет первый элемент в контейнере с ключом, эквивалентным k. Возвращает элемент, node_­type владеющий элементом, если он найден, в противном случае - пустой node_­type. log(a.size())
a.​extract(​q) node_­type удаляет элемент, на который указывает q. Возвращает node_­type владение этим элементом. амортизированная постоянная
a.merge(a2) void Requires: a.get_­allocator() == a2.get_­allocator().
Пытается извлечь каждый элемент a2 и вставить его с a помощью объекта сравнения a. В контейнерах с уникальными ключами, если есть элемент a с ключом, эквивалентным ключу элемента из a2, то этот элемент не извлекается из a2.
Postconditions: Указатели и ссылки на переданные элементы a2 относятся к тем же элементам, но как членам a. Итераторы, относящиеся к переданным элементам, будут продолжать ссылаться на свои элементы, но теперь они ведут себя как итераторы в a, а не в a2.
Throws: Ничего, если объект сравнения не выбрасывает.
Nlog(a.size()+N), где N имеет значение a2.size().
a.erase(k) size_­type стирает все элементы в контейнере с ключом, эквивалентным k. возвращает количество стертых элементов. log(a.size())+a.count(k)
a.erase(q) iterator стирает элемент, на который указывает q. Возвращает итератор, указывающий на элемент, следующий сразу за q стираемым элементом. Если такого элемента нет, возвращается a.end(). амортизированная постоянная
a.erase(r) iterator стирает элемент, на который указывает r. Возвращает итератор, указывающий на элемент, следующий сразу за r стираемым элементом. Если такого элемента нет, возвращается a.end(). амортизированная постоянная
a.erase(
q1, q2)
iterator стирает все элементы в диапазоне [q1, q2). Возвращает итератор, указывающий на элемент, на который указывает до q2 стирания каких-либо элементов. Если такого элемента не существует, a.end() возвращается. log(a.size())+N, где N имеет значение distance(q1, q2).
a.clear() void a.erase(a.begin(),a.end())
Postconditions: a.empty() возвращается true.
линейно в a.size().
b.find(k) iterator; const_­iterator для постоянного b. возвращает итератор, указывающий на элемент с ключом, эквивалентным k, или b.end() если такой элемент не найден логарифмический
a_­tran.
find(ke)
iterator; const_­iterator для постоянного a_­tran. возвращает итератор, указывающий на элемент с r таким ключом , что !c(r, ke) && !c(ke, r), или a_­tran.end() если такой элемент не найден логарифмический
b.count(k) size_­type возвращает количество элементов с ключом, эквивалентным k log(b.size())+b.count(k)
a_­tran.
count(ke)
size_­type возвращает количество элементов с r таким ключом , что !c(r, ke) && !c(ke, r) log(a_tran.size())+a_tran.count(ke)
b.lower_­bound(k) iterator; const_­iterator для постоянного b. возвращает итератор, указывающий на первый элемент с ключом не меньше чем k, или b.end() если такой элемент не найден. логарифмический
a_­tran.
lower_­bound(kl)
iterator; const_­iterator для постоянного a_­tran. возвращает итератор, указывающий на первый элемент с r таким ключом , что !c(r, kl)или, a_­tran.end() если такой элемент не найден. логарифмический
b.upper_­bound(k) iterator; const_­iterator для постоянного b. возвращает итератор, указывающий на первый элемент с ключом больше чем k, или b.end() если такой элемент не найден. логарифмический
a_­tran.
upper_­bound(ku)
iterator; const_­iterator для постоянного a_­tran. возвращает итератор, указывающий на первый элемент с r таким ключом , что c(ku, r)или, a_­tran.end() если такой элемент не найден. логарифмический
b.equal_­range(k) pair<​iterator, iterator>; pair<​const_­iterator, const_­iterator> для постоянного b. эквивалентно make_­pair(b.lower_­bound(k), b.upper_­bound(k)). логарифмический
a_­tran.
equal_­range(ke)
pair<​iterator, iterator>; pair<​const_­iterator, const_­iterator> для постоянного a_­tran. эквивалентно . make_­pair(
a_­tran.lower_­bound(ke), a_­tran.upper_­bound(ke))
логарифмический

Члены insert и emplace не должны влиять на действительность итераторов и ссылок на контейнер, а erase члены должны аннулировать только итераторы и ссылки на удаленные элементы.

Эти extract члены недействительной только итераторы для удаленного элемента; указатели и ссылки на удаленный элемент остаются в силе. Однако доступ к элементу через такие указатели и ссылки, когда элемент принадлежит a, node_­type является неопределенным поведением. Ссылки и указатели на элемент, полученные, когда он принадлежит a, node_­type становятся недействительными, если элемент успешно вставлен.

Фундаментальным свойством итераторов ассоциативных контейнеров является то, что они перебирают контейнеры в неубывающем порядке ключей, где неубывающий порядок определяется сравнением, которое использовалось для их создания. Для любых двух разыменяемых итераторов i и j таких, что расстояние от i до j положительно, выполняется следующее условие:

value_comp(*j, *i) == false

Для ассоциативных контейнеров с уникальными ключами выполняется более сильное условие:

value_comp(*i, *j) != false

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

Шаблоны функций - членов find, count, lower_­bound, upper_­bound, и equal_­range не должен участвовать в разрешении перегрузки , если qualified-id Compare​::​is_­transparent не является действительным , и обозначает тип ([temp.deduct]).

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

  • У него есть InputIterator параметр шаблона, и для этого параметра выводится тип, который не квалифицируется как итератор ввода.

  • У него есть Allocator параметр шаблона, и для этого параметра выводится тип, который не квалифицируется как распределитель.

  • У него есть Compare параметр шаблона, и для этого параметра выводится тип, который квалифицируется как распределитель.

26.2.6.1 Exception safety guarantees [associative.reqmts.except]

Для ассоциативных контейнеров ни одна clear() функция не генерирует исключение. erase(k) не генерирует исключение, если это исключение не вызвано Compare объектом контейнера (если есть).

Для ассоциативных контейнеров, если какая-либо операция из функции insert или, emplace вставляющая один элемент, вызывает исключение, вставка не имеет никакого эффекта.

Для ассоциативных контейнеров ни одна swap функция не генерирует исключение, если это исключение не вызвано заменой объекта контейнера Compare (если таковой имеется).

26.2.7 Unordered associative containers [unord.req]

Неупорядоченные ассоциативные контейнеры обеспечивают возможность быстрого извлечения данных на основе ключей. Сложность наихудшего случая для большинства операций является линейной, но средний случай намного быстрее. Библиотека предоставляет четыре неупорядоченные ассоциативные контейнеры: unordered_­set, unordered_­map, unordered_­multiset, и unordered_­multimap.

Неупорядоченные ассоциативные контейнеры соответствуют requirements for Containers, за исключением того, что выражения a == b и a != b имеют другую семантику, чем для других типов контейнеров.

Каждый неупорядоченный ассоциативный контейнер параметризуется Keyтипом объекта функции, Hash который соответствует Hash requirements и действует как хэш-функция для значений аргументов типа Key, а также двоичным предикатом, Pred который индуцирует отношение эквивалентности для значений типа Key. Кроме того, unordered_­map и unordered_­multimap связать произвольный файл mapped type T с расширением Key.

Тип объекта контейнера, Hash обозначаемый значком, hash называется объектом hash function контейнера. Тип объекта контейнера, Pred обозначаемый значком, pred называется объектомkey equality predicate контейнера.

Два значения k1 и k2 типа Key считаются эквивалентными, если предикат равенства ключей контейнера возвращается true при передаче этих значений. Если k1 и k2 эквивалентны, хеш-функция контейнера должна возвращать одинаковое значение для обоих. [ Note: Таким образом, когда неупорядоченный ассоциативный контейнер создается с Pred параметром, не являющимся параметром по умолчанию, ему обычно также требуется параметр, не являющийся Hash параметром по умолчанию . ] Для любых двух ключей в одном и том же контейнере вызов всегда должен возвращать одно и то же значение. Для любого ключа в контейнере вызов всегда должен возвращать одно и то же значение. end note k1 k2 pred(k1, k2) k hash(k)

Неупорядоченный ассоциативный контейнер поддерживает, unique keys если он может содержать не более одного элемента для каждого ключа. В противном случае поддерживает equivalent keys. unordered_­set и unordered_­map поддерживают уникальные ключи. unordered_­multiset и unordered_­multimap поддержка эквивалентных ключей. В контейнерах, поддерживающих эквивалентные ключи, элементы с эквивалентными ключами соседствуют друг с другом в порядке итерации контейнера. Таким образом, хотя абсолютный порядок элементов в неупорядоченном контейнере не указан, его элементы сгруппированы так equivalent-key groups , что все элементы каждой группы имеют эквивалентные ключи. Операции мутации над неупорядоченными контейнерами должны сохранять относительный порядок элементов в каждой группе эквивалентных ключей, если не указано иное.

Для unordered_­set и unordered_­multiset тип значения совпадает с типом ключа. Ибо так unordered_­map и unordered_­multimap есть pair<const Key, T>.

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

Элементы неупорядоченного ассоциативного контейнера организованы в buckets. Ключи с одинаковым хэш-кодом появляются в одном сегменте. Количество сегментов автоматически увеличивается по мере добавления элементов в неупорядоченный ассоциативный контейнер, поэтому среднее количество элементов в сегменте остается ниже установленного предела. Повторное хеширование делает недействительными итераторы, изменяет порядок между элементами и изменяет элементы сегментов, но не делает недействительными указатели или ссылки на элементы. Для unordered_­multiset и unordered_­multimapповторное хеширование сохраняет относительный порядок эквивалентных элементов.

Неупорядоченные ассоциативные контейнеры соответствуют всем требованиям Allocator-aware containers, за исключением unordered_­map и unordered_­multimap, требования, указанные value_­type в таблице, 83 применяются вместо key_­type и mapped_­type. [ Note: Например, key_­type и mapped_­type иногда требуется, чтобы он был, CopyAssignable даже если связанный value_­type, pair<const key_­type, mapped_­type>не является CopyAssignable. ] end note

В таблице 91: X обозначает неупорядоченный ассоциативный контейнерный класс, a обозначает значение типа X, a2 обозначает значение типа с узлами, совместимыми с типом X (таблица 89), b обозначает возможное значение типа const X, a_­uniq обозначает значение типа, X когда X поддерживает уникальные ключи, a_­eq обозначает значение типа, X когда X поддерживает эквивалентные ключи, i и j обозначает итераторы ввода, на которые ссылаются value_­type, [i, j) обозначает допустимый диапазон p и q2 обозначает допустимые итераторы констант для a, q и q1 обозначает допустимые разыменяемые итераторы констант для a, r обозначает допустимый разыменяемый итератор для a, [q1, q2) обозначает допустимый диапазон в a, il обозначает значение типа initializer_­list<value_­type>, t обозначает значение типа X​::​value_­type, k обозначает значение типа key_­type, hf обозначает возможное значение типа const hasher, eq обозначает возможное значение типа const key_­equal, n обозначает значение типа size_­type, z обозначает значение типа floatи nh обозначает не -const r значение типа X​::​node_­type.

Таблица 91 - Требования к неупорядоченному ассоциативному контейнеру (в дополнение к контейнеру)
ВыражениеТип возвратаУтверждение / примечаниеСложность
до / после состояния
X​::​key_­type Key время компиляции
X​::​mapped_­type (unordered_­map и unordered_­multimap только) T время компиляции
X​::​value_­type (unordered_­set и unordered_­multiset только) Key Requires:  value_­type это Erasable из X время компиляции
X​::​value_­type (unordered_­map и unordered_­multimap только) pair<const Key, T> Requires:  value_­type это Erasable из X время компиляции
X​::​hasher Hash Hash должен быть унарным типом функционального объекта, так что выражение hf(k) имеет тип size_­t. время компиляции
X​::​key_­equal Pred Requires:  Pred есть CopyConstructible.
Pred должен быть двоичным предикатом, который принимает два аргумента типа Key. Pred является отношением эквивалентности.
время компиляции
X​::​local_­iterator Тип итератора, категория, тип значения, тип различия, указатель и ссылочный тип которого совпадают с типом итератора X​::​iterator. local_­iterator Объект может быть использован для итерации через одно ведро, но не может быть использован для итерации по ковшам. время компиляции
X​::​const_­local_­iterator Тип итератора, категория, тип значения, тип различия, указатель и ссылочный тип которого совпадают с типом итератора X​::​const_­iterator. const_­local_­iterator Объект может быть использован для итерации через одно ведро, но не может быть использован для итерации по ковшам. время компиляции
X​::​node_­type специализация node_­handle шаблона класса, так что общедоступные вложенные типы являются теми же типами, что и соответствующие типы в X. видеть [container.node] время компиляции
X(n, hf, eq)
X a(n, hf, eq);
X Effects:  Создает пустой контейнер, по крайней мере n , с ведрами, используя hf в качестве хеш-функции и eq в качестве ключевого предиката равенства. O(n)
X(n, hf)
X a(n, hf);
X Requires:  key_­equal есть DefaultConstructible.
Effects:  Создает пустой контейнер, по крайней мере n , с ведрами, используя hf в качестве хеш-функции и key_­equal() в качестве ключевого предиката равенства.
O(n)
X(n)
X a(n);
X Requires:  hasher и key_­equal есть DefaultConstructible.
Effects:  Создает пустой контейнер, по крайней мере n , с ведрами, используя hasher() в качестве хеш-функции и key_­equal() в качестве ключевого предиката равенства.
O(n)
X()
X a;
X Requires:  hasher и key_­equal есть DefaultConstructible.
Effects:  Создает пустой контейнер с неопределенным количеством сегментов, используя hasher() в качестве хеш-функции и key_­equal() в качестве ключевого предиката равенства.
постоянный
X(i, j, n, hf, eq)
X a(i, j, n, hf, eq);
X Requires:  value_­type находится EmplaceConstructible в X от *i.
Effects:  Создает пустой контейнер как минимум с n корзинами, используя hf в качестве хеш-функции и eq в качестве ключевого предиката равенства, и вставляет [i, j) в него элементы из .
Средний случай O(N) (N это distance(i, j)), в худшем случае O(N2)
X(i, j, n, hf)
X a(i, j, n, hf);
X Requires:  key_­equal есть DefaultConstructible. value_­type находится EmplaceConstructible в X от *i.
Effects:  Создает пустой контейнер как минимум с n корзинами, используя hf в качестве хеш-функции и key_­equal() в качестве ключевого предиката равенства, и вставляет [i, j) в него элементы из .
Средний случай O(N) (N это distance(i, j)), в худшем случае O(N2)
X(i, j, n)
X a(i, j, n);
X Requires:  hasher и key_­equal есть DefaultConstructible. value_­type находится EmplaceConstructible в X от *i.
Effects:  Создает пустой контейнер как минимум с n корзинами, используя hasher() в качестве хеш-функции и key_­equal() в качестве ключевого предиката равенства, и вставляет [i, j) в него элементы из .
Средний случай O(N) (N это distance(i, j)), в худшем случае O(N2)
X(i, j)
X a(i, j);
X Requires:  hasher и key_­equal есть DefaultConstructible. value_­type находится EmplaceConstructible в X от *i.
Effects:  Создает пустой контейнер с неопределенным количеством сегментов, используя hasher() в качестве хэш-функции и key_­equal() в качестве ключевого предиката равенства, и вставляет [i, j) в него элементы из .
Средний случай O(N) (N это distance(i, j)), в худшем случае O(N2)
X(il) X То же, что и X(il.begin(), il.end()). То же, что и X(il.begin(), il.end()).
X(il, n) X То же, что и X(il.begin(), il.end(), n). То же, что и X(il.begin(), il.end(), n).
X(il, n, hf) X То же, что и X(il.begin(), il.end(), n, hf). То же, что и X(il.begin(), il.end(), n, hf).
X(il, n, hf, eq) X То же, что и X(il.begin(), il.end(), n, hf, eq). То же, что и X(il.begin(), il.end(), n, hf, eq).
X(b)
X a(b);
X Конструктор копирования. В дополнение к требованиям Table 83, копирует хэш-функцию, предикат и максимальный коэффициент загрузки. Средний случай линейный по b.size(), худший квадратичный.
a = b X& Оператор присваивания копий. В дополнение к требованиям Table 83, копирует хэш-функцию, предикат и максимальный коэффициент загрузки. Средний случай линейный по b.size(), худший квадратичный.
a = il X& Requires:  value_­type находится CopyInsertable в X и CopyAssignable.
Effects:  Назначает диапазон [il.begin(), il.end()) в a. Все существующие элементы a либо присваиваются, либо уничтожаются.
То же, что и a = X(il).
b.hash_­function() hasher Возвращает bхеш-функцию. постоянный
b.key_­eq() key_­equal Возвращает bпредикат равенства ключей. постоянный
a_­uniq. emplace(args) pair<iterator, bool> Requires:  value_­type должен быть EmplaceConstructible в X от args.
Effects:  Вставляет value_­type объект, t созданный с помощью std​::​forward<​Args​>(​args)... if и только если в контейнере нет элемента с ключом, эквивалентным ключу t. bool Компонент возвращаемой пары true тогда и только тогда , когда имеет место вставка, а итератор компонент из точек пары к элементу с ключом , эквивалентным ключом t.
Средний случай O(1), худший случай O(a_uniq.size()).
a_­eq.emplace(args) iterator Requires:  value_­type должен быть EmplaceConstructible в X от args.
Effects:  Вставляет value_­type объект, созданный t с помощью, std​::​forward<​Args>(​args)... и возвращает итератор, указывающий на вновь вставленный элемент.
Средний случай O(1), худший случай O(a_eq.size()).
a.emplace_­hint(p, args) iterator Requires:  value_­type должен быть EmplaceConstructible в X от args.
Effects:  Эквивалентно a.emplace( std​::​forward<​Args>(​args)...). Возвращаемое значение - это итератор, указывающий на элемент с ключом, эквивалентным вновь вставленному элементу. Это const_­iterator p подсказка, указывающая, где должен начинаться поиск. Реализациям разрешено игнорировать подсказку.
Средний случай O(1), худший случай O(a.size()).
a_­uniq.insert(t) pair<iterator, bool> Requires:  Если t - неконстантное выражение rvalue, value_­type должно быть MoveInsertable в X; в противном случае value_­type будет CopyInsertable в X.
Effects:  Вставляет t тогда и только тогда, когда в контейнере нет элемента с ключом, эквивалентным ключу t. bool Компонент возвращаемой пары указывает , имеет ли место вставки, и iterator компонент указывает на элемент с ключом , эквивалентным ключом t.
Средний случай O(1), худший случай O(a_uniq.size()).
a_­eq.insert(t) iterator Requires:  Если t - неконстантное выражение rvalue, value_­type должно быть MoveInsertable в X; в противном случае value_­type будет CopyInsertable в X.
Effects:  Вставляет tи возвращает итератор, указывающий на вновь вставленный элемент.
Средний случай O(1), худший случай O(a_eq.size()).
a.insert(p, t) iterator Requires:  Если t - неконстантное выражение rvalue, value_­type должно быть MoveInsertable в X; в противном случае value_­type будет CopyInsertable в X.
Effects:  Эквивалентно a.insert (t). Возвращаемое значение - итератор, указывающий на элемент с ключом, эквивалентным ключу t. Итератор p - это подсказка, указывающая, где должен начинаться поиск. Реализациям разрешено игнорировать подсказку.
Средний случай O(1), худший случай O(a.size()).
a.insert(i, j) void Requires:  value_­type должен быть EmplaceConstructible в X от *i.
Requires: i и j не являются итераторами в a. Эквивалентно a.insert(t) для каждого элемента в [i,j).
Средний случай O(N), где N есть distance(i, j). Худший случай O(N(a.size()+1)).
a.insert(il) void То же, что и a.insert(il.begin(), il.end()). То же, что и a.insert( il.begin(), il.end()).
a_­uniq.
insert(nh)
insert_­return_­type Requires: nh пусто или a_­uniq.get_­allocator() == nh.get_­allocator().
Effects: Если nh пусто, не действует. В противном случае вставляет элемент, владельцем которого является, nh тогда и только тогда, когда в контейнере нет элемента с ключом, эквивалентным nh.key().
Postconditions: Если nh пусто, inserted есть false, position есть end()и node пусто. В противном случае, если вставка имела место, inserted is true, position указывает на вставленный элемент и node является пустым; если вставка не удалась, inserted это false, node имеет предыдущее значение nh, и position указывает на элемент с ключом , эквивалентным nh.key().
Средний случай O(1), худший случай O(a_uniq.size()).
a_­eq.
insert(nh)
iterator Requires: nh пусто или a_­eq.get_­allocator() == nh.get_­allocator().
Effects: Если nh пусто, не действует и возвращается a_­eq.end(). В противном случае вставляет элемент, которым владеет, nh и возвращает итератор, указывающий на вновь вставленный элемент.
Postconditions: nh пустой.
Средний случай O(1), худший случай O(a_eq.size()).
a.insert(q, nh) iterator Requires: nh пусто или a.get_­allocator() == nh.get_­allocator().
Effects: Если nh пусто, не действует и возвращается a.end(). В противном случае вставляет элемент, принадлежащий пользователю nh тогда и только тогда, когда нет элемента с ключом, эквивалентным nh.key() в контейнерах с уникальными ключами; всегда вставляет элемент, которым владеет, nh в контейнеры с эквивалентными ключами. Всегда возвращает итератор, указывающий на элемент с ключом, эквивалентным nh.key(). Итератор q - это подсказка, указывающая, где должен начинаться поиск. Реализациям разрешено игнорировать подсказку.
Postconditions: nh пусто, если вставка прошла успешно, не изменяется, если вставка не удалась.
Средний случай O(1), худший случай O(a.size()).
a.extract(k) node_­type Удаляет элемент в контейнере с ключом, эквивалентным k. Возвращает элемент, node_­type владеющий элементом, если он найден, в противном случае - пустой node_­type. Средний случай O(1), худший случай O(a.size()).
a.extract(q) node_­type Удаляет элемент, на который указывает q. Возвращает node_­type владение этим элементом. Средний случай O(1), худший случай O(a.size()).
a.merge(a2) void Requires: a.get_­allocator() == a2.get_­allocator().
Пытается извлечь каждый элемент a2 и вставить его, a используя хеш-функцию и предикат равенства ключей a. В контейнерах с уникальными ключами, если есть элемент a с ключом, эквивалентным ключу элемента из a2, то этот элемент не извлекается из a2. Postconditions: Указатели и ссылки на переданные элементы a2 относятся к тем же элементам, но как членам a. Итераторы, относящиеся к переданным элементам, и все итераторы, на которые ссылаются, a будут признаны недействительными, но итераторы для оставшихся элементов a2 останутся действительными.
Throws: Ничего, если не выбрасывает хэш-функция или предикат равенства ключей.
Средний случай O(N), где N есть a2.size(). Худший случай O(N*a.size()+N).
a.erase(k) size_­type Удаляет все элементы с ключом, эквивалентным k. Возвращает количество стертых элементов. Средний случай O(a.count(k)). Худший случай O(a.size()).
a.erase(q) iterator Удаляет элемент, на который указывает q. Возвращает итератор, следующий сразу q за стиранием. Средний случай O(1), худший случай O(a.size()).
a.erase(r) iterator Удаляет элемент, на который указывает r. Возвращает итератор, следующий сразу r за стиранием. Средний случай O(1), худший случай O(a.size()).
a.erase(q1, q2) iterator Удаляет все элементы в диапазоне [q1, q2). Возвращает итератор сразу после стертых элементов до стирания. Средний случай, линейный по distance(q1, q2), худший случай O(a.size()).
a.clear() void Удаляет все элементы в контейнере. Postconditions: a.empty() возвращается true Линейный вход a.size().
b.find(k) iterator;
const_­iterator для конст b.
Возвращает итератор, указывающий на элемент с ключом, эквивалентным k, или b.end() если такой элемент не существует. Средний случай O(1), худший случай O(b.size()).
b.count(k) size_­type Возвращает количество элементов с ключом, эквивалентным k. Средний случай O(b.count(k)), худший случай O(b.size()).
b.equal_­range(k) pair<iterator, iterator>;
pair<const_­iterator, const_­iterator> для конст b.
Возвращает диапазон, содержащий все элементы с ключами, эквивалентными k. Возвращает, make_­pair(b.end(), b.end()) если таких элементов не существует. Средний случай O(b.count(k)). Худший случай O(b.size()).
b.bucket_­count() size_­type Возвращает количество содержащихся сегментов b . Постоянный
b.max_­bucket_­count() size_­type Возвращает верхнюю границу количества сегментов, которые b могут когда-либо содержаться. Постоянный
b.bucket(k) size_­type Requires: b.bucket_­count() > 0.
Возвращает индекс корзины, в которой k были бы найдены элементы с ключами, эквивалентными , если бы такой элемент существовал. Postconditions: возвращаемое значение должно быть в диапазоне [0, b.bucket_­count()).
Постоянный
b.bucket_­size(n) size_­type Requires: n должен быть в пределах [0, b.bucket_­count()). Возвращает количество элементов в n th корзине. O(b.bucket_size(n))
b.begin(n) local_­iterator;
const_­local_­iterator для конст b.
Requires: n должен быть в пределах [0, b.bucket_­count()). b.begin(n) возвращает итератор, ссылающийся на первый элемент в корзине. Если ведро пустое, то b.begin(n) == b.end(n). Постоянный
b.end(n) local_­iterator;
const_­local_­iterator для конст b.
Requires: n должен быть в пределах [0, b.bucket_­count()). b.end(n) возвращает итератор, который является последним значением для сегмента. Постоянный
b.cbegin(n) const_­local_­iterator Requires: n должен быть в пределах [0, b.bucket_­count()). Примечание. [b.cbegin(n), b.cend(n)) Это допустимый диапазон, содержащий все элементы в n th сегменте. Постоянный
b.cend(n) const_­local_­iterator Requires: n должен быть в пределах [0, b.bucket_­count()). Постоянный
b.load_­factor() float Возвращает среднее количество элементов в ведре. Постоянный
b.max_­load_­factor() float Возвращает положительное число, при котором контейнер пытается сохранить коэффициент загрузки меньше или равным. Контейнер автоматически увеличивает количество ковшей по мере необходимости, чтобы коэффициент загрузки не превышал этого числа. Постоянный
a.max_­load_­factor(z) void Requires: z должен быть положительным. Может изменить максимальный коэффициент загрузки контейнера, используя z как подсказку. Постоянный
a.rehash(n) void Postconditions: a.bucket_­count() >= a.size() / a.max_­load_­factor() и a.bucket_­count() >= n. Средний случай линейный по a.size(), худший квадратичный.
a.reserve(n) void То же, что и a.rehash(ceil(n / a.max_­load_­factor())). Средний случай линейный по a.size(), худший квадратичный.

Два неупорядоченных контейнера a и b сравнение равны, если a.size() == b.size() и для каждой[Ea1, Ea2) полученной группы с a.equal_­range(Ea1)эквивалентным ключом существует группа с эквивалентным ключом, [Eb1, Eb2) полученная из b.equal_­range(Ea1), такая, что is_­permutation(Ea1, Ea2, Eb1, Eb2) возвращает true. Для unordered_­set и unordered_­mapсложность operator== (т. Е. Количество вызовов == оператора value_­type, предиката, возвращаемого key_­eq()функцией, и хешера, возвращаемого функцией hash_­function()) пропорциональна N в среднем случае и N2 в худшем случае, где N - a. размер(). Для unordered_­multiset и unordered_­multimapсложность operator== пропорциональна E2i в среднем случае и N2 в худшем случае, где N есть a.size(), и Ei - размер группы ith эквивалентных ключей в a. Однако, если соответствующие элементы каждой соответствующей пары групп эквивалентных ключей Eai и Ebi расположены в одном и том же порядке (как это обычно бывает, например, если a и b являются неизмененными копиями одного и того же контейнера), то средняя сложность для unordered_­multiset и unordered_­multimap становится пропорциональным N (но сохраняется сложность наихудшего случая O(N2), например, для патологически плохой хеш-функции). Поведение программы, которая использует operator== или operator!= на неупорядоченных контейнерах, не определено, если объекты функции Hash и Pred соответственно не имеют одинакового поведения для обоих контейнеров, а функция сравнения на равенство для Key является уточнением257 разделения на группы с эквивалентными ключами, созданными с помощью Pred.

Типы итераторов iterator и const_­iterator неупорядоченного ассоциативного контейнера относятся как минимум к категории прямого итератора. Для неупорядоченных ассоциативных контейнеров , где тип ключа и тип значения являются такими же, как iterator и const_­iterator постоянные итераторы.

Члены insert и emplace не должны влиять на действительность ссылок на элементы контейнера, но могут сделать недействительными все итераторы контейнера. В erase членах аннулируют только итераторы и ссылки на стертых элементы, и сохранить относительный порядок элементов, которые не стирается.

Члены insert и emplace не должны влиять на допустимость итераторов, если (N+n) <= z * B, где N - количество элементов в контейнере до операции вставки, n - количество вставленных элементов, B - количество z контейнеров и максимальный коэффициент загрузки контейнера.

Эти extract члены недействительной только итераторы для удаленного элемента, и сохранить относительный порядок элементов, которые не стерты; указатели и ссылки на удаленный элемент остаются в силе. Однако доступ к элементу через такие указатели и ссылки, когда элемент принадлежит a, node_­type является неопределенным поведением. Ссылки и указатели на элемент, полученные, когда он принадлежит a, node_­type становятся недействительными, если элемент успешно вставлен.

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

  • У него есть InputIterator параметр шаблона, и для этого параметра выводится тип, который не квалифицируется как итератор ввода.

  • У него есть Allocator параметр шаблона, и для этого параметра выводится тип, который не квалифицируется как распределитель.

  • У него есть Hash параметр шаблона, и для этого параметра выводится целочисленный тип или тип, который квалифицируется как распределитель.

  • У него есть Pred параметр шаблона, и для этого параметра выводится тип, который квалифицируется как распределитель.

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

26.2.7.1 Exception safety guarantees [unord.req.except]

Для неупорядоченных ассоциативных контейнеров ни одна clear() функция не генерирует исключение. erase(k) не генерирует исключение, если только это исключение не вызвано контейнером Hash или Pred объектом (если есть).

Для неупорядоченных ассоциативных контейнеров, если исключение вызвано любой операцией, отличной от хэш-функции контейнера, внутри функцииinsert или, emplace вставляющей один элемент, вставка не имеет никакого эффекта.

Для неупорядоченных ассоциативных контейнеров ни одна swap функция не генерирует исключение, если только это исключение не вызвано заменой контейнера Hash или Pred объекта (если есть).

Для неупорядоченных ассоциативных контейнеров, если исключение выбрасывается из rehash() функции, отличной от хэш-функции контейнера или функции сравнения, rehash() функция не имеет никакого эффекта.