Контейнеры - это объекты, в которых хранятся другие объекты. Они контролируют выделение и освобождение этих объектов с помощью конструкторов, деструкторов, операций вставки и стирания.
Все требования к сложности в этом разделе указаны исключительно в терминах количества операций с содержащимися объектами. [ 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.
Выражение | Тип возврата | Оперативный | Утверждение / примечание | Сложность |
семантика | до / после состояния | |||
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 note allocator_traits<allocator_type>::select_on_container_copy_constructionconst allocator_type& Note: Allocator — end note swap()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.
Выражение | Тип возврата | Утверждение / примечание | Сложность |
до / после состояния | |||
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 если не указано иное.
Выражение | Тип возврата | Оперативный | Утверждение / примечание | Сложность |
семантика | до / после состояния | |||
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.
Выражение | Тип возврата | Утверждение / примечание | Сложность |
до / после состояния | |||
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{}) правильно сформировано, когда рассматривается как неоцененный операнд.
Для целей 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
Контейнер последовательности организует конечный набор объектов одного типа в строго линейную структуру. Библиотека обеспечивает четыре основных видов контейнеров последовательности: 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&&.
Сложность выражений зависит от последовательности.
Выражение | Тип возврата | Утверждение / примечание |
до / после состояния | ||
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, 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.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 перечислены операции, которые предусмотрены для одних типов контейнеров последовательностей, но не для других. Реализация должна обеспечивать эти операции для всех типов контейнеров, показанных в столбце «контейнер», и должна реализовывать их так, чтобы использовать амортизированное постоянное время.
Выражение | Тип возврата | Операционная семантика | Контейнер |
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 |
A node handle - это объект, который принимает владение одним элементом из associative container или unordered associative container. Его можно использовать для передачи этого владения другому контейнеру с совместимыми узлами. Контейнеры с совместимыми узлами имеют одинаковый тип дескриптора узла. Элементы могут передаваться в любом направлении между типами контейнеров в одной строке таблицы 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); } };
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_.
~node_handle();
value_type& value() const;
Returns: Ссылка на value_type подобъект в container_node_type объекте, на который указывает ptr_.
key_type& key() const;
Returns: Неконстантная ссылка на key_type член value_type подобъекта в container_node_type объекте, на который указывает ptr_.
mapped_type& mapped() const;
Returns: Ссылка на mapped_type член value_type подобъекта в container_node_type объекте, на который указывает ptr_.
allocator_type get_allocator() const;
explicit operator bool() const noexcept;
bool empty() const noexcept;
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_.
Ассоциативные контейнеры с уникальными ключами и неупорядоченные контейнеры с уникальными ключами имеют функцию-член, insert которая возвращает вложенный тип insert_return_type. Этот возвращаемый тип является специализацией типа, указанного в этом подпункте.
template <class Iterator, class NodeType>
struct INSERT_RETURN_TYPE
{
Iterator position;
bool inserted;
NodeType node;
};
Ассоциативные контейнеры обеспечивают быстрый поиск данных на основе ключей. Библиотека обеспечивает четыре основных вида ассоциативных контейнеров: 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.
Выражение | Тип возврата | Утверждение / примечание | Сложность |
до / после состояния | |||
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 параметр шаблона, и для этого параметра выводится тип, который квалифицируется как распределитель.
Для ассоциативных контейнеров ни одна clear() функция не генерирует исключение. erase(k) не генерирует исключение, если это исключение не вызвано Compare объектом контейнера (если есть).
Для ассоциативных контейнеров, если какая-либо операция из функции insert или, emplace вставляющая один элемент, вызывает исключение, вставка не имеет никакого эффекта.
Неупорядоченные ассоциативные контейнеры обеспечивают возможность быстрого извлечения данных на основе ключей. Сложность наихудшего случая для большинства операций является линейной, но средний случай намного быстрее. Библиотека предоставляет четыре неупорядоченные ассоциативные контейнеры: 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.
Выражение | Тип возврата | Утверждение / примечание | Сложность |
до / после состояния | |||
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 параметр шаблона, и для этого параметра выводится тип, который квалифицируется как распределитель.
Сравнение равенства - это уточнение разделения, если никакие два сравниваемых объекта не попадают в разные разделы.
Для неупорядоченных ассоциативных контейнеров ни одна clear() функция не генерирует исключение. erase(k) не генерирует исключение, если только это исключение не вызвано контейнером Hash или Pred объектом (если есть).
Для неупорядоченных ассоциативных контейнеров, если исключение вызвано любой операцией, отличной от хэш-функции контейнера, внутри функцииinsert или, emplace вставляющей один элемент, вставка не имеет никакого эффекта.
Для неупорядоченных ассоциативных контейнеров ни одна swap функция не генерирует исключение, если только это исключение не вызвано заменой контейнера Hash или Pred объекта (если есть).