std::optional<T>::optional
constexpr optional() noexcept;
constexpr optional( std::nullopt_t ) noexcept;
|
(1) | (seit C++17) |
constexpr optional( const optional& other );
|
(2) | (seit C++17) |
constexpr optional( optional&& other ) noexcept(/* see below */);
|
(3) | (seit C++17) |
template < class U >
optional( const optional<U>& other );
|
(4) | (seit C++17) (constexpr seit C++20) (bedingt explizit) |
template < class U >
optional( optional<U>&& other );
|
(5) | (seit C++17) (constexpr seit C++20) (bedingt explizit) |
template< class... Args >
constexpr explicit optional( std::in_place_t, Args&&... args );
|
(6) | (seit C++17) |
template< class U, class... Args >
constexpr explicit optional( std::in_place_t,
std::initializer_list<U> ilist,
Args&&... args );
|
(7) | (seit C++17) |
template < class U = std::remove_cv_t<T> >
constexpr optional( U&& value );
|
(8) | (seit C++17) (bedingt explizit) |
Konstruiert ein neues optional-Objekt.
other einen Wert enthält, initialisiert den enthaltenen Wert wie durch Direktinitialisierung (aber nicht durch Direkt-Listeninitialisierung) eines Objekts vom Typ T mit dem Ausdruck *other. Wenn other keinen Wert enthält, konstruiert ein Objekt, das keinen Wert enthält.
- Dieser Konstruktor ist als gelöscht definiert, wenn
std::is_copy_constructible_v<T>falseist. - Es ist ein trivialer Konstruktor, wenn
std::is_trivially_copy_constructible_v<T>trueist.
other einen Wert enthält, initialisiert den enthaltenen Wert wie durch Direktinitialisierung (aber nicht durch Direkt-Listeninitialisierung) eines Objekts vom Typ T mit dem Ausdruck std::move(*other) und macht other nicht leer: ein verschobenes std::optional enthält immer noch einen Wert, aber der Wert selbst wurde verschoben. Wenn other keinen Wert enthält, konstruiert ein Objekt, das keinen Wert enthält.
- Dieser Konstruktor nimmt nicht an der Überladungsauflösung teil, es sei denn,
std::is_move_constructible_v<T>trueist. - Es ist ein trivialer Konstruktor, wenn
std::is_trivially_move_constructible_v<T>trueist.
other keinen Wert enthält, konstruiert ein optional-Objekt, das keinen Wert enthält. Andernfalls konstruiert ein optional-Objekt, das einen Wert enthält, initialisiert wie durch Direktinitialisierung (aber nicht durch Direkt-Listeninitialisierung) eines Objekts vom Typ T mit dem Ausdruck *other.
- Dieser Konstruktor nimmt nicht an der Überladungsauflösung teil, es sei denn, die folgenden Bedingungen sind erfüllt:
std::is_constructible_v<T, const U&>trueist.- Wenn
Tnicht (möglicherweise cv-qualifiziert)boolist, istTnicht konstruierbar oder konvertierbar von einem Ausdruck des Typs (möglicherweiseconst)std::optional<U>, d.h.converts_from_any_cvref<T, std::optional<U>>falseist, wobeiconverts_from_any_cvrefunten beschrieben wird.
- Dieser Konstruktor ist
explicitgenau dann, wennstd::is_convertible_v<const U&, T>falseist.
other keinen Wert enthält, konstruiert ein optional-Objekt, das keinen Wert enthält. Andernfalls konstruiert ein optional-Objekt, das einen Wert enthält, initialisiert wie durch Direktinitialisierung (aber nicht durch Direkt-Listeninitialisierung) eines Objekts vom Typ T mit dem Ausdruck std::move(*other).
- Dieser Konstruktor nimmt nicht an der Überladungsauflösung teil, es sei denn, die folgenden Bedingungen sind erfüllt:
std::is_constructible_v<T, U&&>trueist.- Wenn
Tnicht (möglicherweise cv-qualifiziert)boolist, istTnicht konstruierbar oder konvertierbar von einem Ausdruck des Typs (möglicherweiseconst)std::optional<U>, d.h.converts_from_any_cvref<T, std::optional<U>>falseist, wobeiconverts_from_any_cvrefunten beschrieben wird.
- Dieser Konstruktor ist
explicitgenau dann, wennstd::is_convertible_v<U&&, T>falseist.
T aus den Argumenten std::forward<Args>(args)....
- Wenn der ausgewählte Konstruktor von
Teinconstexpr-Konstruktor ist, ist dieser Konstruktor einconstexpr-Konstruktor. - Die Funktion nimmt nicht an der Überladungsauflösung teil, es sei denn,
std::is_constructible_v<T, Args...>trueist.
T aus den Argumenten ilist, std::forward<Args>(args)....
- Wenn der ausgewählte Konstruktor von
Teinconstexpr-Konstruktor ist, ist dieser Konstruktor einconstexpr-Konstruktor. - Die Funktion nimmt nicht an der Überladungsauflösung teil, es sei denn,
std::is_constructible_v<T, std::initializer_list<U>&, Args...>trueist.
T mit dem Ausdruck std::forward<U>(value).
- Wenn der ausgewählte Konstruktor von
Teinconstexpr-Konstruktor ist, ist dieser Konstruktor einconstexpr-Konstruktor. - Dieser Konstruktor nimmt nicht an der Überladungsauflösung teil, es sei denn, die folgenden Bedingungen sind erfüllt:
std::is_constructible_v<T, U&&>trueist.std::decay_t<U>(bis C++20)std::remove_cvref_t<U>(seit C++20) ist weder std::in_place_t nochstd::optional<T>.- Wenn
T(möglicherweise cv-qualifiziert)boolist, iststd::decay_t<U>(bis C++20)std::remove_cvref_t<U>(seit C++20) keine Spezialisierung vonstd::optional.
- Dieser Konstruktor ist
explicitgenau dann, wennstd::is_convertible_v<U&&, T>falseist.
Die Hilfsvariablenvorlage converts_from_any_cvref ist äquivalent zu:
template< class T, class W >
constexpr bool converts_from_any_cvref =
std::disjunction_v<std::is_constructible<T, W&>, std::is_convertible<W&, T>,
std::is_constructible<T, W>, std::is_convertible<W, T>,
std::is_constructible<T, const W&>, std::is_convertible<const W&, T>,
std::is_constructible<T, const W>, std::is_convertible<const W, T>>;
Parameter
| other | - |
ein anderes
optional
Objekt, dessen enthaltene Wert kopiert wird
|
| value | - | Wert, mit dem der enthaltene Wert initialisiert wird |
| args... | - | Argumente, mit denen der enthaltene Wert initialisiert wird |
| ilist | - | Initialisierungsliste, mit der der enthaltene Wert initialisiert wird |
Exceptions
T
geworfen wird.
T
geworfen wird. Hat die folgende
T
geworfen wird.
Hinweise
Vor der Lösung von
LWG Issue 3836
wählte die Konstruktion eines
std::
optional
<
bool
>
aus
std::
optional
<
U
>
Überladung
(
9
)
anstelle der Überladungen
(
5,6
)
, falls
U
nicht
bool
ist. Dies liegt daran, dass die Überladungen
(
5,6
)
nicht an der Überladungsauflösung teilnahmen, wenn
T
(in diesem Fall
bool
) von
std::
optional
<
U
>
konstruiert oder konvertiert werden kann, aber
std::optional::operator bool
die Konversion für jedes
U
ermöglicht.
Folglich enthält das konstruierte std:: optional < bool > immer einen Wert. Dieser Wert wird dadurch bestimmt, ob das bereitgestellte std:: optional < U > Objekt einen Wert enthält, und nicht durch den bool Wert, der direkt aus dem enthaltenen Wert initialisiert wurde:
std::optional<bool> op_false(false); std::optional<int> op_zero(0); std::optional<int> from_bool(op_false); // OK: enthält 0 (initialisiert von false) std::optional<bool> from_int(op_zero); // DEFEKT (LWG 3836): enthält true, weil // op_zero einen Wert enthält, selbst wenn die // Initialisierung von bool mit diesem Wert false ergibt
| Feature-Test Makro | Wert | Std | Feature |
|---|---|---|---|
__cpp_lib_optional
|
202106L
|
(C++20)
(DR20) |
Vollständig constexpr ( 5,6 ) |
Beispiel
#include <iostream> #include <optional> #include <string> int main() { std::optional<int> o1, // leer o2 = 1, // Initialisierung aus Rvalue o3 = o2; // Kopierkonstruktor // Ruft std::string( initializer_list<CharT> ) Konstruktor auf std::optional<std::string> o4(std::in_place, {'a', 'b', 'c'}); // Ruft std::string( size_type count, CharT ch ) Konstruktor auf std::optional<std::string> o5(std::in_place, 3, 'A'); // Move-konstruiert von std::string unter Verwendung des Deduction Guide zur Typauswahl std::optional o6(std::string{"deduction"}); std::cout << *o2 << ' ' << *o3 << ' ' << *o4 << ' ' << *o5 << ' ' << *o6 << '\n'; }
Ausgabe:
1 1 abc AAA deduction
Fehlerberichte
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 3836 | C++17 |
beim Konstruieren eines
std::
optional
<
bool
>
aus std:: optional < U > würde die Überladungsauflösung Überladung ( 9 ) auswählen, falls
U
nicht
bool
ist
|
wählt in diesem Fall immer den
konvertierenden Kopier-/Move- Konstruktor aus |
| LWG 3886 | C++17 |
das Standard-Template-Argument von Überladung
(
9
)
war
T
|
geändert zu std:: remove_cv_t < T > |
| P0602R4 | C++17 |
Kopier-/Move-Konstruktoren könnten nicht trivial sein
selbst wenn der zugrundeliegende Konstruktor trivial ist |
muss
Trivialität weitergeben |
| P2231R1 | C++20 |
Überladungen
(
5,6
)
von einem anderen
std::optional
waren nicht
constexpr
|
als constexpr festgelegt |
Siehe auch
|
(C++17)
|
erstellt ein
optional
-Objekt
(Funktions-Template) |