table of contents
std::optional::optional(3) | C++ Standard Libary | std::optional::optional(3) |
NAME¶
std::optional::optional - std::optional::optional
Synopsis¶
constexpr optional() noexcept; (since
constexpr optional( std::nullopt_t ) (1) C++17)
noexcept;
constexpr optional( const optional& other (2) (since
); C++17)
constexpr optional( optional&& other ) (3) (since
noexcept(/* see below */); C++17)
(since C++17)
template < class U > (until C++20)
optional( const optional<U>& other ); (conditionally
explicit)
template < class U > (since C++20)
constexpr optional( const optional<U>& (conditionally
other ); explicit)
(since C++17)
template < class U > (until C++20)
optional( optional<U>&& other ); (conditionally
explicit)
template < class U > (since C++20)
constexpr optional( optional<U>&& other ); (conditionally
explicit)
template< class... Args > (4)
constexpr explicit optional( (6) (since C++17)
std::in_place_t, Args&&... args );
template< class U, class... Args > (5)
constexpr explicit optional(
std::in_place_t,
(7) (since C++17)
std::initializer_list<U> ilist,
Args&&...
args );
template < class U = T > (since C++17)
constexpr optional( U&& value ); (8) (conditionally
explicit)
Constructs a new optional object.
1) Constructs an object that does not contain a value.
2) Copy constructor: If other contains a value, initializes the contained
value as
if direct-initializing (but not direct-list-initializing) an object of type T
with
the expression *other. If other does not contain a value, constructs an
object that
does not contain a value.
* This constructor is defined as deleted if
std::is_copy_constructible_v<T> is
false.
* It is a trivial constructor if
std::is_trivially_copy_constructible_v<T> is
true.
3) Move constructor: If other contains a value, initializes the contained
value as
if direct-initializing (but not direct-list-initializing) an object of type T
with
the expression std::move(*other) and does not make other empty: a moved-from
std::optional still contains a value, but the value itself is moved from. If
other
does not contain a value, constructs an object that does not contain a value.
* This constructor does not participate in overload resolution unless
std::is_move_constructible_v<T> is true.
* It is a trivial constructor if
std::is_trivially_move_constructible_v<T> is
true.
4) Converting copy constructor: If other does not contain a value, constructs
an
optional object that does not contain a value. Otherwise, constructs an
optional
object that contains a value, initialized as if direct-initializing (but not
direct-list-initializing) an object of type T with the expression *other.
* This constructor does not participate in overload resolution unless the
following conditions are met:
* std::is_constructible_v<T, const U&> is true.
* If T is not (possibly cv-qualified) bool, T is not constructible or
convertible from any expression of type (possibly const)
std::optional<U>,
i.e., the following 8 values are all 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>
* This constructor is explicit if and only if std::is_convertible_v<const
U&, T>
is false.
5) Converting move constructor: If other does not contain a value, constructs
an
optional object that does not contain a value. Otherwise, constructs an
optional
object that contains a value, initialized as if direct-initializing (but not
direct-list-initializing) an object of type T with the expression
std::move(*other).
* This constructor does not participate in overload resolution unless the
following conditions are met:
* std::is_constructible_v<T, U&&> is true.
* If T is not (possibly cv-qualified) bool, T is not constructible or
convertible from any expression of type (possibly const)
std::optional<U>,
i.e., the following 8 values are all 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>
* This constructor is explicit if and only if
std::is_convertible_v<U&&, T> is
false.
6) Constructs an optional object that contains a value, initialized as if
direct-initializing (but not direct-list-initializing) an object of type T
from the
arguments std::forward<Args>(args)....
* If the selected constructor of T is a constexpr constructor, this
constructor is
a constexpr constructor.
* The function does not participate in the overload resolution unless
std::is_constructible_v<T, Args...> is true.
7) Constructs an optional object that contains a value, initialized as if
direct-initializing (but not direct-list-initializing) an object of type T
from the
arguments ilist, std::forward<Args>(args)....
* If the selected constructor of T is a constexpr constructor, this
constructor is
a constexpr constructor.
* The function does not participate in the overload resolution unless
std::is_constructible_v<T, std::initializer_list<U>&,
Args...> is true.
8) Constructs an optional object that contains a value, initialized as if
direct-initializing (but not direct-list-initializing) an object of type T
with the
expression std::forward<U>(value).
* If the selected constructor of T is a constexpr constructor, this
constructor is
a constexpr constructor.
* This constructor does not participate in overload resolution unless the
following conditions are met:
* std::is_constructible_v<T, U&&> is true.
* std::decay_t<U>
(until C++20)
std::remove_cvref_t<U>
(since C++20) is neither std::in_place_t nor std::optional<T>.
* If 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 of std::optional.
* This constructor is explicit if and only if
std::is_convertible_v<U&&, T> is
false.
Parameters¶
other - another optional 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
Exceptions¶
2) Throws any exception thrown by the constructor of T.
3) Throws any exception thrown by the constructor of T. Has the following
noexcept specification:
noexcept(std::is_nothrow_move_constructible<T>::value)
4-8) Throws any exception thrown by the constructor of T.
Deduction guides
Notes¶
Before the resolution of LWG issue 3836, constructing an
std::optional<bool> from
std::optional<U> would select overload (8) instead of overloads
(4,5) if U is not
bool. This is because overloads (4,5) did not participate in overload
resolution if
T (bool in this case) can be constructed or converted from
std::optional<U>, but
std::optional::operator bool makes the conversion possible for any U.
As a result, the constructed std::optional<bool> always contains a
value. That value
is determined by whether the provided std::optional<U> object contains
a value,
rather than the bool 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_0); // DEFECT (LWG 3836): contains true
// because op_0 contains a value, even if
// initializing bool from that value gives false
Example¶
// Run this code
#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> ) constructor
std::optional<std::string> o4(std::in_place, {'a', 'b', 'c'});
// calls std::string( size_type count, CharT ch ) constructor
std::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
Defect reports
The following behavior-changing defect reports were applied retroactively to
previously published C++ standards.
DR Applied to Behavior as published Correct behavior
when constructing an std::optional<bool> always selects the
LWG 3836 C++17 from std::optional<U>, the overload converting copy/move
resolution constructor in this
would select overload (8) if U is not bool case
copy/move constructors might not be required to
P0602R4 C++17 trivial propagate triviality
even if underlying constructor is trivial
converting constructors from another
P2231R1 C++20 std::optional was made constexpr
not constexpr while the required
operations can be in C++20
See also¶
make_optional creates an optional object
(C++17) (function template)
Category:¶
* conditionally noexcept
2024.06.10 | http://cppreference.com |