std::optional<T>::optional
constexpr optional() noexcept; |
(1) | (seit C++17) |
constexpr optional( std::nullopt_t ) noexcept; |
(2) | (seit C++17) |
constexpr optional( const optional& other ); |
(3) | (seit C++17) |
constexpr optional( optional&& other ) noexcept(/* siehe unten */); |
(4) | (seit C++17) |
template< class U > optional( const optional<U>& other ); |
(5) | (seit C++17) (constexpr seit C++20) (bedingt explizit) |
template< class U > optional( optional<U>&& other ); |
(6) | (seit C++17) (constexpr seit C++20) (bedingt explizit) |
template< class... Args > constexpr explicit optional( std::in_place_t, Args&&... args ); |
(7) | (seit C++17) |
template< class U, class... Args > constexpr explicit optional( std::in_place_t, |
(8) | (seit C++17) |
template< class U = std::remove_cv_t<T> > constexpr optional( U&& value ); |
(9) | (seit C++17) (bedingt explizit) |
Erzeugt ein neues optional-Objekt.
Inhalt |
[bearbeiten] Parameter
| Sonstiges | - | ein weiteres optional-Objekt, dessen enthaltener Wert kopiert wird |
| value | - | Wert, mit dem der enthaltene Wert initialisiert werden soll |
| args... | - | Argumente, mit denen der enthaltene Wert initialisiert werden soll |
| ilist | - | Initialisierungsliste, mit der der enthaltene Wert initialisiert werden soll |
[bearbeiten] Effekte
| Überladung | Initialisierungsmethode | Initialisierer für den enthaltenen Wert | has_value() nach der Konstruktion |
|---|---|---|---|
| (1) | N/A | - | false |
| (2) | |||
| (3) | Direkt (keine Liste) | *other | other.has_value()
|
| (4) | std::move(*other) | ||
| (5) | *other | ||
| (6) | std::move(*other) | ||
| (7) | std::forward<Args>(args)... | true | |
| (8) | ilist, std::forward<Args>(args)... | ||
| (9) | std::forward<U>(value) |
[bearbeiten] Beschränkungen und ergänzende Informationen
- std::is_constructible_v<T, const U&> ist true.
- Wenn
Tnicht (möglicherweise cv-qualifiziertes) bool ist, sind die folgenden 8 Werte 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_constructible_v<T, U> ist true.
- Wenn
Tnicht (möglicherweise cv-qualifiziertes) bool ist, sind die folgenden 8 Werte 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>
T ein constexpr-Konstruktor ist, ist dieser Konstruktor ebenfalls ein constexpr-Konstruktor.T ein constexpr-Konstruktor ist, ist dieser Konstruktor ebenfalls ein constexpr-Konstruktor.- std::is_constructible_v<T, U> ist true.
- std::decay_t<U>(bis C++20)std::remove_cvref_t<U>(seit C++20) weder std::in_place_t noch std::optional<T> ist.
- Wenn
T(möglicherweise cv-qualifiziertes) bool ist, ist std::decay_t<U>(bis C++20)std::remove_cvref_t<U>(seit C++20) keine Spezialisierung vonstd::optional.
T ein constexpr-Konstruktor ist, ist dieser Konstruktor ebenfalls ein constexpr-Konstruktor.- ↑ 1.0 1.1 Mit anderen Worten,
Tkann weder von einem Ausdruck des Typs (möglicherweise const-qualifiziertes) std::optional<U> konstruiert noch in diesen konvertiert werden.
[bearbeiten] Ausnahmen
T geworfen wird.T geworfen wird. Hat die folgendeT geworfen wird.[bearbeiten] Deduktionshilfen
[bearbeiten] Hinweise
Vor der Auflösung von LWG-Problem 3836 würde das Erstellen eines std::optional<bool> aus std::optional<U> die Überladung (9) anstelle der Überladungen (5,6) auswählen, wenn U nicht bool ist. Dies liegt daran, dass die Überladungen (5,6) nicht an der Überladungsauflösung teilnehmen, wenn T (in diesem Fall bool) aus std::optional<U> konstruiert oder in diesen konvertiert werden kann, aber std::optional::operator bool die Konvertierung für jedes U ermöglicht.
Daher enthält der erstellte 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 direkt aus dem enthaltenen Wert initialisierten bool-Wert.
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_zero); // DEFECT (LWG 3836): contains true because // op_zero contains a value, even if initializing // bool from that value gives false
| Feature-Test-Makro | Wert | Std | Feature |
|---|---|---|---|
__cpp_lib_optional |
202106L |
(C++20) (DR20) |
Vollständig constexpr (5,6) |
[bearbeiten] Beispiel
#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'; }
Ausgabe
1 1 abc AAA deduction
[bearbeiten] 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 Erstellen eines std::optional<bool> aus std::optional<U>, die Überladungsauflösung würde Überladung (9) wählen, wenn U nicht bool ist |
wählt immer die konvertierende Kopie-/Verschiebungs- Konstruktor in diesem Fall |
| LWG 3886 | C++17 | das Standard-Template-Argument von Überladung (9) war T |
geändert zu std::remove_cv_t<T> |
| P0602R4 | C++17 | Kopie-/Verschiebungskonstruktoren sind möglicherweise nicht trivial auch wenn der zugrunde liegende Konstruktor trivial ist |
erforderlich, um Trivialität weiterzugeben |
| P2231R1 | C++20 | Überladungen (5,6) von einem anderen std::optional war nicht constexpr |
zu constexpr gemacht |
[bearbeiten] Siehe auch
| (C++17) |
erzeugt ein optional-Objekt(function template) |