В то время как в C ++ 03 у нас только была возможность копировать объекты построения / копирования, мы получили два дополнительных, гораздо более мощных инструмента для создания объектов и один дополнительный инструмент для назначения объектов: перемещениеКонструкция, назначение и использование конструкции (на основе идеальной переадресации).
Благодаря этому стандарт дает value_type
возможности для контейнеров в своих требованиях.Например, вам разрешено хранить unique_ptr
s, которые предназначены только для перемещения, в std::vector
, если вы не используете никаких операций, требующих CopyConstructible , CopyInsertable или CopyAssignable (например, присвоение одного контейнера другому).
Могут ли объекты этого класса легально храниться в контейнерах STL?
Да , нет требований о том, что может использоваться в контейнере, для которого создан определенный value_type
, даже упоминающий оператор адреса в любом случае.
§17.6.3.1 [utility.arg.requirements]
Определения шаблонов в стандартной библиотеке C ++ относятся к различным именованным требованиям, подробности которых приведены в таблицах 17–24.
(Таблицы 17 и 18 - Сопоставимые требования)
Table 19 — DefaultConstructible requirements [defaultconstructible]
Expression Post-condition
T t; object t is default-initialized
T u{}; object u is value-initialized
T() a temporary object of type T is value-initialized
T{}
Table 20 — MoveConstructible requirements [moveconstructible]
Expression Post-condition
T u = rv; u is equivalent to the value of rv before the construction
T(rv) T(rv) is equivalent to the value of rv before the construction
rv’s state is unspecified
Table 21 — CopyConstructible requirements (in addition to MoveConstructible) [copyconstructible]
Expression Post-condition
T u = v; the value of v is unchanged and is equivalent to u
T(v) the value of v is unchanged and is equivalent to T(v)
Table 22 — MoveAssignable requirements [moveassignable]
Expression Return type Return value Post-condition
t = rv T& t t is equivalent to the value of
rv before the assignment
rv’s state is unspecified.
Table 23 — CopyAssignable requirements(in addition to MoveAssignable) [copyassignable]
Expression Return type Return value Post-condition
t = v T& t t is equivalent to v, the value of
v is unchanged
Table 24 — Destructible requirements [destructible]
Expression Post-condition
u.~T() All resources owned by u are reclaimed, no exception is propagated.
Затем мы также получили требования к контейнерам.Они основаны на их типах распределителя:
§23.2.1 [container.requirements.general] p13
Все контейнеры, определенные в этом разделе и в (21.4), за исключением массива, отвечают дополнительным требованиям, связанным с распределителемконтейнер, как описано в Таблице 99. Для данного типа контейнера X
с типом allocator, идентичным A
и value_type
, идентичным T
и дано значение l m
типа A
, указатель p
типа T*
, выражение v
типа T
и значение rv
типа T
, определены следующие термины.(Если X
не учитывает распределителя, приведенные ниже термины определяются следующим образом: A
были std::allocator<T>
.)
T
is CopyInsertable в X
означает, что следующее выражение правильно сформировано: allocator_traits<A>::construct(m, p, v);
T
is MoveInsertable в X
означает, что следующее выражение правильно сформировано: allocator_traits<A>::construct(m, p, rv);
T
is EmplaceConstructible в X
с args
, дляноль или более аргументов args
, означает, что следующее выражение правильно сформировано: allocator_traits<A>::construct(m, p, args);
Выдержка из таблицы для контейнеров последовательности(где p
является действительным константным итератором, а t
является lvalue типа T
):
a.insert(p,t)
Требуется: T
должен быть CopyInsertable в X
.Для vector
и deque
, T
также должны иметь значение CopyAssignable.
Эффекты: Вставляет копиюt до p.
Если вы никогда не используете этот конкретный вариант insert
(и другие члены, для которых требуется CopyInsertible), ваш тип не обязательно должен быть CopyInsertable.Легко как то.То же самое касается всех остальных участников.Требование только о том, что должно быть выполнено , является требованием уничтожения (логично, не правда ли?).