Spec-Zone.ru › C++

Обёртка с возможностью присваивания (C++20)

template< class T >
    requires std::copy_constructible<T> && std::is_object_v<T>
class /*copyable-box*/;
(начиная с C++20)
(до C++23)
(только для иллюстрации*)
template< class T >
    requires std::move_constructible<T> && std::is_object_v<T>
class /*movable-box*/;
(начиная с C++23)
(только для иллюстрации*)

ranges::single_view, ranges::repeat_view,(начиная с C++23) и адаптеры диапазонов, хранящие вызываемый объект, описываются в терминах шаблона класса, предназначенного только для иллюстрации: copyable-box(до C++23)movable-box(начиная с C++23). Приведённое здесь имя используется только для иллюстрации.

Обёртка ведёт себя точно так же, как std::optional<T>, за исключением того, что конструктор по умолчанию, оператор копирующего присваивания и оператор перемещающего присваивания (условно) отличаются от соответствующих операторов std::optional. Этот класс дополняет T возможностью присваивания, когда это необходимо, и всегда удовлетворяет требованиям copyableили movable(начиная с C++23).

Если T уже является copyable или если одновременно std::is_nothrow_move_constructible_v<T> и std::is_nothrow_copy_constructible_v<T> являются true, /*copyable-box*/<T> может хранить только объект T, поскольку всегда содержит значение.

(до C++23)

Если T

  • уже является copyable, или
  • является copy_constructible, а std::is_nothrow_move_constructible_v<T> и std::is_nothrow_copy_constructible_v<T> одновременно являются true, или
  • не удовлетворяет требованиям copy_constructible, но удовлетворяет требованиям movable, или
  • не удовлетворяет требованиям copy_constructible, но std::is_nothrow_move_constructible_v<T> является true,

/*movable-box*/<T> может хранить только объект T, поскольку всегда содержит значение.

(начиная с C++23)

Параметры шаблона

T - тип хранимого значения; должен быть типом объекта, удовлетворяющим требованиям copy_constructible(до C++23)move_constructible(начиная с C++23)

Функции-члены

Конструктор по умолчанию

constexpr /*copyable-box*/() noexcept(std::is_nothrow_default_constructible_v<T>)
    requires std::default_initializable<T>
    : /*copyable-box*/(std::in_place) { }
(начиная с C++20)
(до C++23)
constexpr /*movable-box*/() noexcept(std::is_nothrow_default_constructible_v<T>)
    requires std::default_initializable<T>
    : /*movable-box*/(std::in_place) { }
(начиная с C++23)

Конструктор по умолчанию предоставляется тогда и только тогда, когда T удовлетворяет требованиям default_initializable.

Созданная конструктором по умолчанию обёртка содержит объект T, инициализированный значением.

Операторы присваивания

constexpr /*copyable-box*/& operator=(const /*copyable-box*/& other);
    noexcept(/* see below */);
(1) (начиная с C++20)
(до C++23)
constexpr /*movable-box*/& operator=(const /*movable-box*/& other);
    noexcept(/* see below */) requires std::copy_constructible<T>;
(начиная с C++23)
constexpr /*copyable-box*/& operator=(/*copyable-box*/&& other)
    noexcept(std::is_nothrow_move_constructible_v<T>);
(2) (начиная с C++20)
(до C++23)
constexpr /*movable-box*/& operator=(/*movable-box*/&& other)
    noexcept(std::is_nothrow_move_constructible_v<T>);
(начиная с C++23)
1) Если std::copyable<T> не удовлетворяет требованиям, оператор копирующего присваивания эквивалентно определяется следующим образом:

constexpr /*copyable-box*/& operator=(const /*copyable-box*/& other) noexcept(std::is_nothrow_copy_constructible_v<T>) { if (this != std::addressof(other)) if (other) emplace(*other); else reset(); return *this; }

(до C++23)

constexpr /*movable-box*/& operator=(const /*movable-box*/& other) noexcept(std::is_nothrow_copy_constructible_v<T>) requires std::copy_constructible<T> { if (this != std::addressof(other)) if (other) emplace(*other); else reset(); return *this; }

(начиная с C++23)
В противном случае он идентичен оператору копирующего присваивания std::optional.
2) Если std::movable<T> не удовлетворяет требованиям, оператор перемещающего присваивания эквивалентно определяется следующим образом:

constexpr /*copyable-box*/& operator=(/*copyable-box*/&& other) noexcept(std::is_nothrow_move_constructible_v<T>) { if (this != std::addressof(other)) if (other) emplace(std::move(*other)); else reset(); return *this; }

(до C++23)

constexpr /*movable-box*/& operator=(/*movable-box*/&& other) noexcept(std::is_nothrow_move_constructible_v<T>) { if (this != std::addressof(other)) if (other) emplace(std::move(*other)); else reset(); return *this; }

(начиная с C++23)
В противном случае он идентичен оператору перемещающего присваивания std::optional.

Члены, идентичные членам std::optional

Функции-члены

(конструктор)
создаёт объект optional
(открытая функция-член std::optional<T>)
(деструктор)
уничтожает хранимое значение, если оно есть
(открытая функция-член std::optional<T>)
operator=
присваивает содержимое
(открытая функция-член std::optional<T>)
Наблюдатели
operator->operator*
получает доступ к хранимому значению
(открытая функция-член std::optional<T>)
operator boolhas_value
проверяет, содержит ли объект значение
(открытая функция-член std::optional<T>)
Модификаторы
reset
уничтожает любое хранимое значение
(открытая функция-член std::optional<T>)
emplace
создаёт хранимое значение на месте
(открытая функция-член std::optional<T>)

Примечания

copyable-box(до C++23)movable-box(начиная с C++23) не содержит значения только в том случае, если

  • T не удовлетворяет требованиям movable или copyable, и при перемещающем или копирующем присваивании соответственно выбрасывается исключение, либо
  • она инициализируется или ей присваивается значение другой обёртки, не содержащей значения.

До принятия P2325R3 в стандарте обёртка называлась semiregular-box и всегда удовлетворяла требованиям semiregular, поскольку конструктор по умолчанию всегда предоставлялся (и мог создать обёртку без значения).

Макрос проверки поддержки возможности Значение Стандарт Возможность
__cpp_lib_ranges 201911L (C++20) Библиотека диапазонов и алгоритмы с ограничениями
202106L (C++20)
(DR)
Представления, не требующие инициализации по умолчанию
202207L (C++23) Ослабление требований к адаптерам диапазонов, позволяющее использовать типы, поддерживающие только перемещение

Отчёты об исправлении ошибок

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

DR Применён к Поведение согласно опубликованной редакции Правильное поведение
P2325R3 C++20 если T не удовлетворяет требованиям default_initializable, конструктор по умолчанию
создаёт обёртку, не содержащую значения
обёртка также
не удовлетворяет требованиям default_initializable
LWG 3572 C++20 условно отличающиеся операторы присваивания не были constexpr сделаны constexpr

См. также

ranges::single_viewviews::single
(C++20)
view, содержащий один элемент заданного значения
(шаблон класса) (объект точки настройки)
ranges::repeat_viewviews::repeat
(C++23)
view, состоящий из последовательности, генерируемой повторным созданием одного и того же значения
(шаблон класса) (объект точки настройки)
ranges::filter_viewviews::filter
(C++20)
view, состоящий из элементов range, удовлетворяющих предикату
(шаблон класса) (объект-адаптер диапазона)
ranges::transform_viewviews::transform
(C++20)
view последовательности, применяющий функцию преобразования к каждому элементу
(шаблон класса) (объект-адаптер диапазона)
ranges::take_while_viewviews::take_while
(C++20)
view, состоящий из начальных элементов другого view до первого элемента, для которого предикат возвращает false
(шаблон класса) (объект-адаптер диапазона)
ranges::drop_while_viewviews::drop_while
(C++20)
view, состоящий из элементов другого view, пропуская начальную подпоследовательность элементов до первого элемента, для которого предикат возвращает false
(шаблон класса) (объект-адаптер диапазона)
ranges::zip_transform_viewviews::zip_transform
(C++23)
view, состоящий из результатов применения функции преобразования к соответствующим элементам адаптированных представлений
(шаблон класса) (объект точки настройки)
ranges::adjacent_transform_viewviews::adjacent_transform
(C++23)
view, состоящий из результатов применения функции преобразования к соседним элементам адаптированного представления
(шаблон класса) (объект-адаптер диапазона)

© cppreference.com
Licensed under the Creative Commons Attribution-ShareAlike Unported License v3.0.
https://en.cppreference.com/cpp/ranges/copyable_wrapper

Spec-Zone.ru

Настройки Оффлайн Что нового Помощь О нас
Spec-Zone .ru
спецификации, руководства, описания, API