std::optional<T>::operator=
Von cppreference.com
optional& operator=( std::nullopt_t ) noexcept; |
(1) | (seit C++17) (constexpr seit C++20) |
constexpr optional& operator=( const optional& other ); |
(2) | (seit C++17) |
constexpr optional& operator= ( optional&& other ) noexcept(/* siehe unten */); |
(3) | (seit C++17) |
template< class U > optional& operator=( const optional<U>& other ); |
(4) | (seit C++17) (constexpr seit C++20) |
template< class U > optional& operator=( optional<U>&& other ); |
(5) | (seit C++17) (constexpr seit C++20) |
template< class U = std::remove_cv_t<T> > optional& operator=( U&& value ); |
(6) | (seit C++17) (constexpr seit C++20) |
Ersetzt den Inhalt von *this durch den Inhalt von other.
1) Wenn *this einen Wert enthält, wird
val ->T::~T() aufgerufen, um den enthaltenen Wert zu zerstören; andernfalls hat dies keine Auswirkung. *this enthält nach diesem Aufruf keinen Wert.2-5) Weist den Zustand von other zu. has_value() gibt nach diesem Aufruf other.has_value() zurück.
| Auswirkung | *this enthält einen Wert | *this enthält keinen Wert |
|---|---|---|
| other enthält einen Wert |
|
|
| other enthält keinen Wert | zerstört den enthaltenen Wert durch Aufruf von val ->T::~T() |
keine Auswirkung |
2) Wenn std::is_copy_constructible_v<T> oder std::is_copy_assignable_v<T> false ist, ist der Zuweisungsoperator als gelöscht definiert.
Wenn std::is_trivially_copy_constructible_v<T>, std::is_trivially_copy_assignable_v<T> und std::is_trivially_destructible_v<T> alle true sind, ist der Zuweisungsoperator trivial.
3) Diese Überladung nimmt nur an der Überladungsauflösung teil, wenn std::is_move_constructible_v<T> und std::is_move_assignable_v<T> beide true sind.
Wenn std::is_trivially_move_constructible_v<T>, std::is_trivially_move_assignable_v<T> und std::is_trivially_destructible_v<T> alle true sind, ist der Zuweisungsoperator trivial.
4,5) Diese Überladungen nehmen nur an der Überladungsauflösung teil, wenn alle folgenden Bedingungen erfüllt sind
- Die folgenden 12 Werte sind alle false[1]
- 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>&&>
- Für Überladung (4) sind std::is_constructible_v<T, const U&> und std::is_assignable_v<T&, const U&> beide true.
- Für Überladung (5) sind std::is_constructible_v<T, U> und std::is_assignable_v<T&, U> beide true.
6) Wenn *this einen Wert enthält, wird std::forward<U>(value) dem enthaltenen Wert zugewiesen; andernfalls wird der enthaltene Wert direkt, nicht über eine Initialisierungsliste, mit std::forward<U>(value) initialisiert. *this enthält nach diesem Aufruf einen Wert.
Diese Überladung nimmt an der Überladungsauflösung teil, nur wenn alle folgenden Bedingungen erfüllt sind
- std::decay_t<U>(bis C++20)std::remove_cvref_t<U>(seit C++20) ist nicht std::optional<T>.
- std::is_constructible_v<T, U> ist true.
- std::is_assignable_v<T&, U> ist true.
- Eine der folgenden Bedingungen ist erfüllt
-
Tist kein Skalarmtyp. - std::decay_t<U> ist nicht
T.
-
- ↑ Mit anderen Worten,
Tist nicht konstruierbar, konvertierbar oder zuweisbar von jedem Ausdruck des Typs (möglicherweise const-qualifiziert) std::optional<U>
Inhalt |
[edit] Parameter
| Sonstiges | - | ein weiteres optional-Objekt, dessen enthaltenen Wert zugewiesen werden soll |
| value | - | Wert, der dem enthaltenen Wert zugewiesen werden soll |
[edit] Rückgabewert
*this
[edit] Ausnahmen
2-6) Wirft jede Ausnahme, die vom Konstruktor oder Zuweisungsoperator von
T geworfen wird. Wenn eine Ausnahme geworfen wird, bleibt der Initialisierungszustand von *this (und von other im Fall von (2-5)) unverändert, d.h. wenn das Objekt einen Wert enthielt, enthält es diesen immer noch, und umgekehrt. Die Inhalte von value und die enthaltenen Werte von *this und other hängen von den Ausnahmesicherheitgarantien der Operation ab, von der die Ausnahme herrührt (Kopierkonstruktor, Zuweisung per Move, etc.).3) Hat Folgendes
noexcept-Spezifikation:
noexcept(std::is_nothrow_move_assignable_v<T> &&
std::is_nothrow_move_constructible_v<T>)
std::is_nothrow_move_constructible_v<T>)
[edit] Anmerkungen
Ein optionales Objekt op kann in ein leeres optionales Objekt mit sowohl op = {}; als auch op = nullopt; umgewandelt werden. Der erste Ausdruck konstruiert ein leeres optional-Objekt mit {} und weist es op zu.
| Feature-Test-Makro | Wert | Std | Feature |
|---|---|---|---|
__cpp_lib_optional |
202106L |
(C++20) (DR20) |
Vollständig constexpr (1), (4-6) |
[edit] Beispiel
Führen Sie diesen Code aus
#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'; }
Ausgabe
abc def
[edit] Fehlermeldungen
Die folgenden Verhaltensändernden Fehlerberichte wurden rückwirkend auf zuvor veröffentlichte C++-Standards angewendet.
| DR | angewendet auf | Verhalten wie veröffentlicht | Korrigiertes Verhalten |
|---|---|---|---|
| LWG 3886 | C++17 | das Standard-Template-Argument von Überladung (6) war T |
geändert zu std::remove_cv_t<T> |
| P0602R4 | C++17 | Kopier-/Move-Zuweisungsoperator sind möglicherweise nicht trivial auch wenn zugrundeliegende Operationen trivial sind |
erforderlich, um Trivialität zu propagieren |
| P2231R1 | C++20 | Überladungen (1,4-6) waren nicht constexpr | zu constexpr gemacht |
[edit] Siehe auch
| konstruiert den enthaltenen Wert in-place (public member function) |