Namespaces
Variants

std::optional<T>:: optional

From cppreference.net
Utilities library
constexpr optional ( ) noexcept ;
(1) (начиная с C++17)
constexpr optional ( std:: nullopt_t ) noexcept ;
(2) (начиная с C++17)
constexpr optional ( const optional & other ) ;
(3) (начиная с C++17)
constexpr optional ( optional && other ) noexcept ( /* см. ниже */ ) ;
(4) (начиная с C++17)
template < class U >
optional ( const optional < U > & other ) ;
(5) (начиная с C++17)
(constexpr начиная с C++20)
(условно explicit)
template < class U >
optional ( optional < U > && other ) ;
(6) (начиная с C++17)
(constexpr начиная с C++20)
(условно explicit)
template < class ... Args >
constexpr explicit optional ( std:: in_place_t , Args && ... args ) ;
(7) (начиная с C++17)
template < class U, class ... Args >

constexpr explicit optional ( std:: in_place_t ,
std:: initializer_list < U > ilist,

Args && ... args ) ;
(8) (начиная с C++17)
template < class U = std:: remove_cv_t < T > >
constexpr optional ( U && value ) ;
(9) (начиная с C++17)
(условно explicit)

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

Содержание

Параметры

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

Эффекты

Перегрузка Способ инициализации Инициализатор для содержащегося значения has_value() после конструирования
( 1 ) Н/Д - false
( 2 )
( 3 ) Прямая (не список) * other other. has_value ( )
  • Если false , содержащееся значение не инициализируется.
( 4 ) std :: move ( * other )
( 5 ) * other
( 6 ) std :: move ( * other )
( 7 ) std:: forward < Args > ( args ) ... true
( 8 ) ilist, std:: forward < Args > ( args ) ...
( 9 ) std:: forward < U > ( value )

Ограничения и дополнительная информация

3) Если std:: is_copy_constructible_v < T > равно false , конструктор определяется как удалённый.
Если std:: is_trivially_copy_constructible_v < T > равно true , конструктор является тривиальным.
4) Эта перегрузка участвует в разрешении перегрузки только если std:: is_move_constructible_v < T > равно true .
Если std:: is_trivially_move_constructible_v < T > равно true , конструктор является тривиальным.
5) Эта перегрузка участвует в разрешении перегрузки только при выполнении всех следующих условий:
Эта перегрузка объявлена как будто с explicit ( ! std:: is_convertible_v < const U & , T > ) .
6) Эта перегрузка участвует в разрешении перегрузки только при выполнении всех следующих условий:
Эта перегрузка объявлена как будто с explicit ( ! std:: is_convertible_v < U, T > ) .
7) Эта перегрузка участвует в разрешении перегрузки только если std:: is_constructible_v < T, Args... > равно true .
Если конструктор T , выбранный для инициализации, является constexpr конструктором, то этот конструктор также является constexpr конструктором.
8) Эта перегрузка участвует в разрешении перегрузки только если std:: is_constructible_v < T, std:: initializer_list < U > & , Args... > равно true .
Если T конструктор, выбранный для инициализации, является constexpr конструктором, то этот конструктор также является constexpr конструктором.
9) Эта перегрузка участвует в разрешении перегрузки только при выполнении всех следующих условий:
Эта перегрузка объявлена как будто с explicit ( ! std:: is_convertible_v < U, T > ) .
Если конструктор T , выбранный для инициализации, является constexpr конструктором, то этот конструктор также является constexpr конструктором.
  1. 1.0 1.1 Другими словами, T не является ни конструируемым, ни конвертируемым из любого выражения типа (возможно, const-квалифицированного) std:: optional < U >

Исключения

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

Руководства по выводу

Примечания

До разрешения LWG issue 3836 , конструирование std:: optional < bool > из std:: optional < U > выбирало перегрузку ( 9 ) вместо перегрузок ( 5,6 ) , если U не является bool . Это происходило потому, что перегрузки ( 5,6 ) не участвовали в разрешении перегрузки, если 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_zero);  // ДЕФЕКТ (LWG 3836): содержит true, потому что
                                        // op_zero содержит значение, даже если инициализация
                                        // bool из этого значения дает false
Макрос тестирования возможностей Значение Стандарт Функция
__cpp_lib_optional 202106L (C++20)
(DR20)
Полностью constexpr ( 5,6 )

Пример

#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 с использованием deduction guide для выбора типа
    std::optional o6(std::string{"deduction"});
    std::cout << *o2 << ' ' << *o3 << ' ' << *o4 << ' ' << *o5  << ' ' << *o6 << '\n';
}

Вывод:

1 1 abc AAA deduction

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

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

DR Applied to Behavior as published Correct behavior
LWG 3836 C++17 при конструировании std:: optional < bool >
из std:: optional < U > разрешение перегрузки
выбирало перегрузку ( 9 ) если U не является bool
всегда выбирает
преобразующий конструктор копирования/перемещения
в этом случае
LWG 3886 C++17 аргумент шаблона по умолчанию для перегрузки ( 9 ) был T изменён на std:: remove_cv_t < T >
P0602R4 C++17 конструкторы копирования/перемещения могли быть нетривиальными
даже если базовый конструктор тривиален
требуется
сохранять тривиальность
P2231R1 C++20 перегрузки ( 5,6 ) из другого std::optional не были constexpr сделаны constexpr

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

создает объект optional
(шаблон функции)