template <class T> class optional { public: using value_type = T; // [optional.ctor], constructors constexpr optional() noexcept; constexpr optional(nullopt_t) noexcept; constexpr optional(const optional&); constexpr optional(optional&&) noexcept(see below); template <class... Args> constexpr explicit optional(in_place_t, Args&&...); template <class U, class... Args> constexpr explicit optional(in_place_t, initializer_list<U>, Args&&...); template <class U = T> EXPLICIT constexpr optional(U&&); template <class U> EXPLICIT optional(const optional<U>&); template <class U> EXPLICIT optional(optional<U>&&); // [optional.dtor], destructor ~optional(); // [optional.assign], assignment optional& operator=(nullopt_t) noexcept; optional& operator=(const optional&); optional& operator=(optional&&) noexcept(see below); template <class U = T> optional& operator=(U&&); template <class U> optional& operator=(const optional<U>&); template <class U> optional& operator=(optional<U>&&); template <class... Args> T& emplace(Args&&...); template <class U, class... Args> T& emplace(initializer_list<U>, Args&&...); // [optional.swap], swap void swap(optional&) noexcept(see below); // [optional.observe], observers constexpr const T* operator->() const; constexpr T* operator->(); constexpr const T& operator*() const&; constexpr T& operator*() &; constexpr T&& operator*() &&; constexpr const T&& operator*() const&&; constexpr explicit operator bool() const noexcept; constexpr bool has_value() const noexcept; constexpr const T& value() const&; constexpr T& value() &; constexpr T&& value() &&; constexpr const T&& value() const&&; template <class U> constexpr T value_or(U&&) const&; template <class U> constexpr T value_or(U&&) &&; // [optional.mod], modifiers void reset() noexcept; private: T *val; // exposition only }; template<class T> optional(T) -> optional<T>;
constexpr optional() noexcept;
constexpr optional(nullopt_t) noexcept;
constexpr optional(const optional& rhs);
constexpr optional(optional&& rhs) noexcept(see below);
template <class... Args> constexpr explicit optional(in_place_t, Args&&... args);
template <class U, class... Args>
constexpr explicit optional(in_place_t, initializer_list<U> il, Args&&... args);
template <class U = T> EXPLICIT constexpr optional(U&& v);
template <class U> EXPLICIT optional(const optional<U>& rhs);
template <class U> EXPLICIT optional(optional<U>&& rhs);
~optional();
val->T::~T()
optional<T>& operator=(nullopt_t) noexcept;
optional<T>& operator=(const optional& rhs);
optional<T>& operator=(optional&& rhs) noexcept(see below);
is_nothrow_move_assignable_v<T> && is_nothrow_move_constructible_v<T>
template <class U = T> optional<T>& operator=(U&& v);
template <class U> optional<T>& operator=(const optional<U>& rhs);
template <class U> optional<T>& operator=(optional<U>&& rhs);
template <class... Args> T& emplace(Args&&... args);
template <class U, class... Args> T& emplace(initializer_list<U> il, Args&&... args);
void swap(optional& rhs) noexcept(see below);
is_nothrow_move_constructible_v<T> && is_nothrow_swappable_v<T>If any exception is thrown, the results of the expressions bool(*this) and bool(rhs) remain unchanged.
constexpr const T* operator->() const;
constexpr T* operator->();
constexpr const T& operator*() const&;
constexpr T& operator*() &;
constexpr T&& operator*() &&;
constexpr const T&& operator*() const&&;
constexpr explicit operator bool() const noexcept;
constexpr bool has_value() const noexcept;
constexpr const T& value() const&;
constexpr T& value() &;
constexpr T&& value() &&;
constexpr const T&& value() const&&;
template <class U> constexpr T value_or(U&& v) const&;
template <class U> constexpr T value_or(U&& v) &&;
return bool(*this) ? std::move(**this) : static_cast<T>(std::forward<U>(v));