|
| |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| Member functions | ||||
optional::optional | ||||
| Observers | ||||
| Iterators | ||||
(C++26) | ||||
(C++26) | ||||
| Monadic operations | ||||
(C++23) | ||||
(C++23) | ||||
(C++23) | ||||
| Modifiers | ||||
| Non-member functions | ||||
| Deduction guides | ||||
| Helper classes | ||||
| Helper objects | ||||
constexpr optional()noexcept; | (1) | (since C++17) |
constexpr optional(std::nullopt_t)noexcept; | (2) | (since C++17) |
constexpr optional(const optional& other); | (3) | (since C++17) |
constexpr optional( optional&& other)noexcept(/* see below */); | (4) | (since C++17) |
template<class U> optional(const optional<U>& other); | (5) | (since C++17) (constexpr since C++20) (conditionally explicit) |
template<class U> optional( optional<U>&& other); | (6) | (since C++17) (constexpr since C++20) (conditionally explicit) |
template<class...Args> constexprexplicit optional(std::in_place_t, Args&&...args); | (7) | (since C++17) |
template<class U,class...Args> constexprexplicit optional(std::in_place_t, | (8) | (since C++17) |
template<class U=std::remove_cv_t<T>> constexpr optional( U&& value); | (9) | (since C++17) (conditionally explicit) |
Constructs a newoptional object.
Contents |
| other | - | anotheroptional object whose contained value is copied |
| value | - | value with which to initialize the contained value |
| args... | - | arguments with which to initialize the contained value |
| ilist | - | initializer list with which to initialize the contained value |
| Overload | Initialization method | Initializer for the contained value | has_value() after construction |
|---|---|---|---|
| (1) | N/A | - | false |
| (2) | |||
| (3) | Direct (non-list) | *other | other.has_value()
|
| (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) |
T is not (possibly cv-qualified)bool, the following 8 values are allfalse[1]:T is not (possibly cv-qualified)bool, the following 8 values are allfalse[1]:T’s constructor selected for the initialization is aconstexpr constructor, this constructor is also aconstexpr constructor.T’s constructor selected for the initialization is aconstexpr constructor, this constructor is also aconstexpr constructor.T is (possibly cv-qualified)bool,std::decay_t<U>(until C++20)std::remove_cvref_t<U>(since C++20) is not a specialization ofstd::optional.T’s constructor selected for the initialization is aconstexpr constructor, this constructor is also aconstexpr constructor.T is neither constructible nor convertible from any expression of type (possibly const-qualified)std::optional<U>T.T. Has the followingT.Before the resolution ofLWG issue 3836, constructing anstd::optional<bool> fromstd::optional<U> would select overload(9) instead of overloads(5,6) ifU is notbool. This is because overloads(5,6) did not participate in overload resolution ifT (bool in this case) can be constructed or converted fromstd::optional<U>, butstd::optional::operator bool makes the conversion possible for anyU.
As a result, the constructedstd::optional<bool> always contains a value. That value is determined by whether the providedstd::optional<U> object contains a value, rather than thebool value direct-initialized from the contained value:
std::optional<bool> op_false(false);std::optional<int> op_zero(0); std::optional<int> from_bool(op_false);// OK: contains 0 (initialized from false)std::optional<bool> from_int(op_zero);// DEFECT (LWG 3836): contains true because// op_zero contains a value, even if initializing// bool from that value gives false
| Feature-test macro | Value | Std | Feature |
|---|---|---|---|
__cpp_lib_optional | 202106L | (C++20) (DR20) | Fullyconstexpr(5,6) |
#include <iostream>#include <optional>#include <string> int main(){std::optional<int> o1,// empty o2=1,// init from rvalue o3= o2;// copy-constructor // calls std::string( initializer_list<CharT> ) constructorstd::optional<std::string> o4(std::in_place,{'a','b','c'}); // calls std::string( size_type count, CharT ch ) constructorstd::optional<std::string> o5(std::in_place,3,'A'); // Move-constructed from std::string using deduction guide to pick the type std::optional o6(std::string{"deduction"}); std::cout<<*o2<<' '<<*o3<<' '<<*o4<<' '<<*o5<<' '<<*o6<<'\n';}
Output:
1 1 abc AAA deduction
The following behavior-changing defect reports were applied retroactively to previously published C++ standards.
| DR | Applied to | Behavior as published | Correct behavior |
|---|---|---|---|
| LWG 3836 | C++17 | when constructing anstd::optional<bool> fromstd::optional<U>, the overload resolution would select overload(9) if U is notbool | always selects the converting copy/move constructor in this case |
| LWG 3886 | C++17 | the default template argument of overload(9) wasT | changed tostd::remove_cv_t<T> |
| P0602R4 | C++17 | copy/move constructors might not be trivial even if underlying constructor is trivial | required to propagate triviality |
| P2231R1 | C++20 | overloads(5,6) from anotherstd::optional was notconstexpr | madeconstexpr |
(C++17) | creates anoptional object(function template)[edit] |