Пространства имён
Варианты
Действия

std::optional<T>::optional

Материал из cppreference.com
 
 
Библиотека утилит
Языковая поддержка
Поддержка типов (базовые типы, RTTI)
Макросы тестирования функциональности библиотеки (C++20)    
Управление динамической памятью
Программные утилиты
Поддержка сопрограмм (C++20)
Вариативные функции
Трёхстороннее сравнение (C++20)
(C++20)
(C++20)(C++20)(C++20)(C++20)(C++20)(C++20)
Общие утилиты
Дата и время
Функциональные объекты
Библиотека форматирования (C++20)
(C++11)
Операторы отношения (устарело в C++20)
Целочисленные функции сравнения
(C++20)(C++20)(C++20)    
(C++20)
Операции обмена и типа
(C++14)
(C++11)
(C++11)
(C++11)
(C++17)
Общие лексические типы
(C++11)
(C++17)
(C++17)
(C++17)
(C++11)
(C++17)
(C++23)
Элементарные преобразования строк
(C++17)
(C++17)
 
std::optional
Функции-элементы
Наблюдатели
Монадические операции
Модификаторы
Функции, не являющиеся элементами
Правила вывода
Вспомогательные классы
Вспомогательные объекты
 
<tbody> </tbody> <tbody class="t-dcl-rev t-dcl-rev-num "> </tbody><tbody> </tbody> <tbody class="t-dcl-rev t-dcl-rev-num "> </tbody><tbody> </tbody>
constexpr optional() noexcept; constexpr optional( std::nullopt_t ) noexcept;
(1) (начиная с C++17)
constexpr optional( const optional& other );
(2) (начиная с C++17)
constexpr optional( optional&& other ) noexcept(/* смотрите ниже */);
(3) (начиная с C++17)
(4)
template < class U > optional( const optional<U>& other );
(начиная с C++17)
(до C++20)
(conditionally explicit)
template < class U > constexpr optional( const optional<U>& other );
(начиная с C++20)
(conditionally explicit)
(5)
template < class U > optional( optional<U>&& other );
(начиная с C++17)
(до C++20)
(conditionally explicit)
template < class U > constexpr optional( optional<U>&& other );
(начиная с C++20)
(conditionally explicit)
template< class... Args > constexpr explicit optional( std::in_place_t, Args&&... args );
(6) (начиная с C++17)
template< class U, class... Args > constexpr explicit optional( std::in_place_t, std::initializer_list<U> ilist, Args&&... args );
(7) (начиная с C++17)
template < class U = T > constexpr optional( U&& value );
(8) (начиная с C++17)
(conditionally explicit)

Создаёт новый объект optional.

1) Создаёт объект, который не содержит значения.
2) Конструктор копирования: если other содержит значение, инициализирует содержащееся значение, как если бы выполнялась прямая инициализация (но не прямая инициализация списком) объекта типа T выражением *other. Если other не содержит значения, создаёт объект, который не содержит значения.
  • Этот конструктор определяется как удалённый, если std::is_copy_constructible_v<T> равно false.
  • Это тривиальный конструктор, если std::is_trivially_copy_constructible_v<T> равно true.
3) Конструктор перемещения: если other содержит значение, инициализирует содержащееся значение, как если бы выполнялась прямая инициализация (но не прямая инициализация списком) объекта типа T выражением std::move(*other) и не делает other пустым: необязательное свойство std::optional по-прежнему содержит значение, но само значение перемещено из. Если other не содержит значения, создаёт объект, который не содержит значения.
  • Этот конструктор не участвует в разрешении перегрузки, если только std::is_move_constructible_v<T> не равно true.
  • Это тривиальный конструктор, если std::is_trivially_move_constructible_v<T> равно true.
4) Преобразующий конструктор копирования: если other не содержит значения, создаёт объект optional, который не содержит значения. Иначе создаёт объект optional, содержащий значение, инициализированное как при прямой инициализации (но не прямой инициализации списком) объекта типа T выражением *other.
  • Этот конструктор не участвует в разрешении перегрузки, если не выполняются следующие условия:
    • std::is_constructible_v<T, const U&> равно true.
    • Если T не является (возможно, cv-квалифицированным) bool, T нельзя создать или преобразовать из любого выражения типа (возможно, const) std::optional<U>, т.е. все следующие 8 значений являются false:
      • std::is_constructible_v<T, std::optional<U>&>
      • std::is_constructible_v<T, const std::optional<U>&>
      • std::is_constructible_v<T, std::optional<U>&&>
      • std::is_constructible_v<T, const std::optional<U>&&>
      • std::is_convertible_v<std::optional<U>&, T>
      • std::is_convertible_v<const std::optional<U>&, T>
      • std::is_convertible_v<std::optional<U>&&, T>
      • std::is_convertible_v<const std::optional<U>&&, T>
  • Этот конструктор является explicit тогда и только тогда, когда std::is_convertible_v<const U&, T> равно false.
5) Преобразующий конструктор перемещения: если other не содержит значения, создаёт объект optional, который не содержит значения. Иначе создаёт объект optional, содержащий значение, инициализированное как при прямой инициализации (но не прямой инициализации списком) объекта типа T выражением std::move(*other).
  • Этот конструктор не участвует в разрешении перегрузки, если не выполняются следующие условия:
    • std::is_constructible_v<T, U&&> равно true.
    • Если T не является (возможно, cv-квалифицированным) bool, T нельзя создать или преобразовать из любого выражения типа (возможно, const) std::optional<U>, т.е. все следующие 8 значений являются false:
      • std::is_constructible_v<T, std::optional<U>&>
      • std::is_constructible_v<T, const std::optional<U>&>
      • std::is_constructible_v<T, std::optional<U>&&>
      • std::is_constructible_v<T, const std::optional<U>&&>
      • std::is_convertible_v<std::optional<U>&, T>
      • std::is_convertible_v<const std::optional<U>&, T>
      • std::is_convertible_v<std::optional<U>&&, T>
      • std::is_convertible_v<const std::optional<U>&&, T>
  • Этот конструктор является explicit тогда и только тогда, когда std::is_convertible_v<U&&, T> равно false.
6) Создаёт объект optional, который содержит значение, инициализированное, как если бы выполнялась прямая инициализация (но не прямая инициализация списком) объекта типа T из аргументов std::forward<Args>(args)....
  • Если выбранный конструктор T является конструктором constexpr, этот конструктор является конструктором constexpr.
  • Функция не участвует в разрешении перегрузки, если только std::is_constructible_v<T, Args...> не равно true.
7) Создаёт объект optional, который содержит значение, инициализированный как при прямой инициализации (но не прямой инициализации списком) объекта типа T из аргументов ilist, std::forward<Args>(args)....
  • Если выбранный конструктор T является конструктором constexpr, этот конструктор является конструктором constexpr.
  • Функция не участвует в разрешении перегрузки, если только std::is_constructible_v<T, std::initializer_list<U>&, Args...> не равно true.
8) Создаёт объект optional, который содержит значение, инициализированный, как если бы при прямой инициализации (но не прямой инициализации списком) объекта типа T выражением std::forward<U>(value).
  • Если выбранный конструктор T является конструктором constexpr, этот конструктор является конструктором constexpr.
  • Этот конструктор не участвует в разрешении перегрузки, если не выполняются следующие условия:
    • std::is_constructible_v<T, U&&> равно true.
    • std::decay_t<U> (до C++20)std::remove_cvref_t<U> (начиная с C++20) не является ни std::in_place_t, ни std::optional<T>.
    • Если T является (возможно, cv-квалифицированным) bool, std::decay_t<U> (до C++20)std::remove_cvref_t<U> (начиная с C++20) не является специализацией std::optional.
  • Этот конструктор является explicit тогда и только тогда, когда std::is_convertible_v<U&&, T> равно false.

Параметры

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

Исключения

2) Выдаёт любое исключение, сгенерированное конструктором T.
3) Выдаёт любое исключение, сгенерированное конструктором T. Имеет следующую
спецификация noexcept:  
noexcept(std::is_nothrow_move_constructible<T>::value)
.
4-8) Выдаёт любое исключение, сгенерированное конструктором T.

Правила вывода

Примечания

До разрешения LWG проблема 3836 создание std::optional<bool> из std::optional<U> выбирало бы перегрузку (8) вместо перегрузок (4,5), если U не равно bool. Это связано с тем, что перегрузки (4,5) не участвовали в разрешении перегрузки, если T (в данном случае bool) мог быть сконструирован или преобразован из std::optional<U>, но std::optional::operator bool делает возможным преобразование для любого U.

В результате сконструированный std::optional<bool> всегда содержит значение. Это значение определяется тем, содержит ли предоставленный объект std::optional<U> значение, а не значение bool, инициализированное напрямую из содержащегося значения:

std::optional<bool> op_false(false);
std::optional<int> op_zero(0);

std::optional<int> from_bool(op_false); // OK: содержит 0 (инициализировано из false)
std::optional<bool> from_int(op_0);     // ДЕФЕКТ (LWG 3836): содержит true,
                                        // поскольку op_0 содержит значение, даже если
                                        // инициализация bool из этого значения даёт false

Пример

#include <iostream>
#include <optional>
#include <string>
int main()
{
    std::optional<int> o1, // пустой
                       o2 = 1, // инициализированный из rvalue
                       o3 = o2; // конструктор копирования
 
    // вызывает конструктор std::string( initializer_list<CharT> )
    std::optional<std::string> o4(std::in_place, {'a', 'b', 'c'});
    
    // вызывает конструктор std::string( size_type count, CharT ch )
    std::optional<std::string> o5(std::in_place, 3, 'A');

    // Конструется перемещением из std::string с использованием принципов вывода
    // для выбора типа

    std::optional o6(std::string{"вывод"});
 
    std::cout << *o2 << ' ' << *o3 << ' ' << *o4 << ' ' << *o5  << ' ' << *o6 << '\n';
}

Вывод:

1 1 abc AAA вывод

Отчёты о дефектах

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

Номер Применён Поведение в стандарте Корректное поведение
LWG 3836 C++17 при создании std::optional<bool> из std::optional<U> разрешение
перегрузки выберет перегрузку (8), если U не bool
в этом случае всегда выбирает
конвертирующий конструктор
копирования/перемещения
WG не указан C++17 конструкторы копирования/перемещения могут быть нетривиальными,
даже если базовый конструктор тривиален
требуется для распространения
тривиальности
WG не указан C++20 конструкторы преобразования из другого std::optional не были constexpr,
в то время как необходимые операции могут быть в C++20
сделаны constexpr

Смотрите также

создаёт объект optional
(шаблон функции) [править]