Namespaces
Variants

std::optional<T>::optional

Von de.cppreference.net
 
 
Hilfsbibliothek
Sprachunterstützung
Typunterstützung (Basistypen, RTTI)
Bibliotheks-Feature-Test-Makros (C++20)
Programm-Hilfsmittel
Funktionen mit variabler Argumentanzahl
Koroutinen-Unterstützung (C++20)
Vertragsunterstützung (C++26)
Dreiveigleich-Vergleich
(C++20)
(C++20)(C++20)(C++20)    
(C++20)(C++20)(C++20)

Allgemeine Hilfsmittel
Relationsoperatoren (veraltet in C++20)
Ganzzahl-Vergleichsfunktionen
(C++20)(C++20)(C++20)    
(C++20)
Swap und Typoperationen
(C++14)
(C++11)
(C++11)
(C++11)
(C++17)
Allgemeine Vokabular-Typen
(C++11)
(C++17)
(C++17)
(C++17)
(C++11)
(C++17)
(C++23)



 
 
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.

1) Konstruiert ein Objekt, das keinen Wert enthält.
2) Kopierkonstruktor: Wenn 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>false ist.
  • Es ist ein trivialer Konstruktor, wenn std::is_trivially_copy_constructible_v<T>true ist.
3) Verschiebekonstruktor: Wenn 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>true ist.
  • Es ist ein trivialer Konstruktor, wenn std::is_trivially_move_constructible_v<T>true ist.
4) Konvertierender Kopierkonstruktor: Wenn 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&>true ist.
    • Wenn T nicht (möglicherweise cv-qualifiziert) bool ist, ist T nicht konstruierbar oder konvertierbar von einem Ausdruck des Typs (möglicherweise const) std::optional<U>, d.h. converts_from_any_cvref<T, std::optional<U>>false ist, wobei converts_from_any_cvref unten beschrieben wird.
  • Dieser Konstruktor ist explicit genau dann, wenn std::is_convertible_v<const U&, T>false ist.
5) Konvertierender Verschiebekonstruktor: Wenn 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&&>true ist.
    • Wenn T nicht (möglicherweise cv-qualifiziert) bool ist, ist T nicht konstruierbar oder konvertierbar von einem Ausdruck des Typs (möglicherweise const) std::optional<U>, d.h. converts_from_any_cvref<T, std::optional<U>>false ist, wobei converts_from_any_cvref unten beschrieben wird.
  • Dieser Konstruktor ist explicit genau dann, wenn std::is_convertible_v<U&&, T>false ist.
6) Konstruiert ein optional-Objekt, das einen Wert enthält, initialisiert wie durch Direktinitialisierung (aber nicht durch Direkt-Listeninitialisierung) eines Objekts vom Typ T aus den Argumenten std::forward<Args>(args)....
  • Wenn der ausgewählte Konstruktor von T ein constexpr-Konstruktor ist, ist dieser Konstruktor ein constexpr-Konstruktor.
  • Die Funktion nimmt nicht an der Überladungsauflösung teil, es sei denn, std::is_constructible_v<T, Args...>true ist.
7) Konstruiert ein optional-Objekt, das einen Wert enthält, initialisiert wie durch Direktinitialisierung (aber nicht durch Direkt-Listeninitialisierung) eines Objekts vom Typ T aus den Argumenten ilist, std::forward<Args>(args)....
  • Wenn der ausgewählte Konstruktor von T ein constexpr-Konstruktor ist, ist dieser Konstruktor ein constexpr-Konstruktor.
  • Die Funktion nimmt nicht an der Überladungsauflösung teil, es sei denn, std::is_constructible_v<T, std::initializer_list<U>&, Args...>true ist.
8) 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::forward<U>(value).
  • Wenn der ausgewählte Konstruktor von T ein constexpr-Konstruktor ist, ist dieser Konstruktor ein constexpr-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&&>true ist.
    • std::decay_t<U>(bis C++20)std::remove_cvref_t<U>(seit C++20) ist weder std::in_place_t noch std::optional<T>.
    • Wenn T (möglicherweise cv-qualifiziert) bool ist, ist std::decay_t<U>(bis C++20)std::remove_cvref_t<U>(seit C++20) keine Spezialisierung von std::optional.
  • Dieser Konstruktor ist explicit genau dann, wenn std::is_convertible_v<U&&, T>false ist.

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

3) Wirft jede Ausnahme, die vom Konstruktor von T geworfen wird.
4) Wirft jede Ausnahme, die vom Konstruktor von T geworfen wird. Hat die folgende
noexcept Spezifikation:
noexcept ( std:: is_nothrow_move_constructible < T > :: value )
5-9) Wirft jede Ausnahme, die vom Konstruktor von 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

erstellt ein optional -Objekt
(Funktions-Template)