std::optional::operator=(3)
π
std::optional::operator=(3) π
okay so bestie, welcome to the std::optional::operator=(3) page from the C++ Standard Libary manual. This is the assignment-operator moment for std::optional, and we are keeping every overload, trait, caveat, and footnote because the details are literally the whole vibe. β¨
π NAME π
std::optional::operator= β std::optional::operator= (the assignment operator for std::optional, no cap).
β¨ Synopsis β¨
optional& operator=( std::nullopt_t ) noexcept; (1) (since C++17)
(constexpr since C++20)
constexpr optional& operator=( const optional& other ); (2) (since C++17)
constexpr optional& operator=( optional&& other ) (3) (since C++17)
noexcept(/* see below */);
template< class U = T > (4) (since C++17)
optional& operator=( U&& value );
(constexpr since C++20)
template< class U > (5) (since C++17)
optional& operator=( const optional<U>& other );
(constexpr since C++20)
template< class U > (6) (since C++17)
optional& operator=( optional<U>&& other );
(constexpr since C++20)
Replaces the contents of *this with the contents of other, bestie. π
1)β If*thiscontains a value before the call, the contained value is destroyed by calling its destructor as if byvalue().T::~T().*thisdoes not contain a value after this call.2,3)β Assigns the state ofother.- If both
*thisandotherdo not contain a value, the function has no effect. - If
*thiscontains a value, butotherdoes not, then the contained value is destroyed by calling its destructor.*thisdoes not contain a value after the call. - If
othercontains a value, then depending on whether*thiscontains a value, the contained value is either direct-initialized or assigned from*other(2) orstd::move(*other)(3). Note that a moved-fromoptionalstill contains a value. - Overload (2) is deleted when either
std::is_copy_constructible_v<T>orstd::is_copy_assignable_v<T>is false. It is trivial ifstd::is_trivially_copy_constructible_v<T>,std::is_trivially_copy_assignable_v<T>andstd::is_trivially_destructible_v<T>are all true. - Overload (3) does not participate in overload resolution when either
std::is_move_constructible_v<T>orstd::is_move_assignable_v<T>is false. It is trivial ifstd::is_trivially_move_constructible_v<T>,std::is_trivially_move_assignable_v<T>andstd::is_trivially_destructible_v<T>are all true.
- If both
4)β Perfect-forwarded assignment: depending on whether*thiscontains a value before the call, the contained value is either direct-initialized fromstd::forward<U>(value)or assigned fromstd::forward<U>(value). The function does not participate in overload resolution unlessstd::decay_t<U>(until C++20)std::remove_cvref_t<U>(since C++20) is notstd::optional<T>,std::is_constructible_v<T, U>is true,std::is_assignable_v<T&, U>is true, and at least one of the following is true:Tis not a scalar type;std::decay_t<U>is notT.
5,6)β Assigns the state ofother.- If both
*thisandotherdo not contain a value, the function has no effect. - If
*thiscontains a value, butotherdoes not, then the contained value is destroyed by calling its destructor.*thisdoes not contain a value after the call. - If
othercontains a value, then depending on whether*thiscontains a value, the contained value is either direct-initialized or assigned from*other(5) orstd::move(*other)(6). Note that a moved-fromoptionalstill contains a value. - These overloads do not participate in overload resolution unless the following conditions are met:
Tis not constructible, convertible, or assignable from any expression of type (possiblyconst)std::optional<U>, i.e., the following 12 type traits 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>std::is_assignable_v<T&, std::optional<U>&>std::is_assignable_v<T&, const std::optional<U>&>std::is_assignable_v<T&, std::optional<U>&&>std::is_assignable_v<T&, const std::optional<U>&&>
- For overload (5),
std::is_constructible_v<T, const U&>andstd::is_assignable_v<T&, const U&>are both true. - For overload (6),
std::is_constructible_v<T, U>andstd::is_assignable_v<T&, U>are both true.
- If both
πΈ Parameters πΈ
otherβ anotheroptionalobject whose contained value to assign.valueβ value to assign to the contained value.
π«Ά Return value π«Ά
*this β that's the whole return value, bestie. π
π₯ Exceptions π₯
2-6) Throws any exception thrown by the constructor or assignment operator of T. If an exception is thrown, the initialization state of *this (and of other in case of (2,3) and (5,6)) is unchanged, i.e. if the object contained a value, it still contains a value, and the other way round. The contents of value and the contained values of *this and other depend on the exception safety guarantees of the operation from which the exception originates (copy-constructor, move-assignment, etc.).
3) Has following noexcept specification:
noexcept(std::is_nothrow_move_assignable_v<T> &&
std::is_nothrow_move_constructible_v<T>)
π¦ Notes π¦
An optional object op may be turned into an empty optional with both op = {}; and op = nullopt;. The first expression constructs an empty optional object with {} and assigns it to op.
β Example β
// Run this code
#include <iostream>
#include <optional>
int main()
{
std::optional<const char*> s1 = "abc", s2; // constructor
s2 = s1; // assignment
s1 = "def"; // decaying assignment (U = char[4], T = const char*)
std::cout << *s2 << ' ' << *s1 << '\n';
}
Output:
abc def
π§ Defect reports π§
The following behavior-changing defect reports were applied retroactively to previously published C++ standards.
P0602R4β applied toC++17. Behavior as published: "copy/move assignment operator may not be required to propagate triviality even if underlying operations are trivial". Correct behavior: "required to propagate triviality".P2231R1β applied toC++20. Behavior as published: "converting assignment operators were not constexpr while the required operations can be in C++20". Correct behavior: "made constexpr".
π See also π
emplaceβ constructs the contained value in-place (public member function).
π Category π
- conditionally noexcept
okay that's the whole page, bestie. Source/version + date from the footer: http://cppreference.com and 2024.06.10, for std::optional::operator=(3). go slay your assignments π
β¨
π¦ where this page comes from
- nixpkgs unstable: stdman 2024.07.05
- opensuse-leap 16.0: stdman 2024.07.05-bp160.1.9 Β· MIT
- π girlified by deepseek-ai/DeepSeek-V4.1-Flash-1017 on : a language model's rewrite of the original, under its terms