std::experimental::propagate_const
| Definiert im Header <experimental/propagate_const> |
||
| template< class T > class propagate_const; |
(Library Fundamentals TS v2) | |
std::experimental::propagate_const ist ein Const-propagierender Wrapper für Zeiger und zeigerähnliche Objekte. Er behandelt den eingehüllten Zeiger als Zeiger auf const, wenn er über einen const-Zugriffspfad angesprochen wird, daher der Name.
Die Klasse erfüllt die Anforderungen an MoveConstructible und MoveAssignable, wenn der zugrundeliegende zeigerähnliche Typ die entsprechende Anforderung erfüllt, aber propagate_const weder CopyConstructible noch CopyAssignable ist.
| Typanforderungen | ||
-T muss ein cv-unqualifizierter Zeiger-auf-Objekt-Typ oder ein cv-unqualifizierter zeigerähnlicher Klassentyp sein, wie unten angegeben. |
Inhalt |
[edit] Anforderungen an zeigerähnliche Klassentypen
Wenn T ein Klassentyp ist, muss er die Anforderungen in diesem Unterabschnitt erfüllen.
Gegeben
-
t, ein modifizierbarer lvalue Ausdruck vom TypT, -
ct, ein lvalue vom Typ const T, der dasselbe Objekt wietbezeichnet (entspricht std::as_const(t) seit C++17), -
element_type, ein Objekttyp.
Die folgenden Ausdrücke müssen gültig sein und ihre angegebenen Effekte haben
| Ausdruck | Rückgabetyp | Vorbedingungen | Operationale Semantik |
|---|---|---|---|
| t.get() | element_type* | ||
| ct.get() | element_type* oder const element_type* | t.get() == ct.get() | |
| *t | element_type& | t.get() != nullptr | *t verweist auf dasselbe Objekt wie *(t.get()) |
| *ct | element_type& oder const element_type& | ct.get() != nullptr | *ct verweist auf dasselbe Objekt wie *(ct.get()) |
| t.operator->() | element_type* | t.get() != nullptr | t.operator->() == t.get() |
| ct.operator->() | element_type* oder const element_type* | ct.get() != nullptr | ct.operator->() == ct.get() |
| (bool)t | bool | (bool)t ist äquivalent zu t.get() != nullptr | |
| (bool)ct | bool | (bool)ct ist äquivalent zu ct.get() != nullptr |
Weiterhin müssen T und const T kontextabhängig in bool konvertierbar sein.
Zusätzlich gilt: Wenn T implizit in element_type* konvertierbar ist, dann muss (element_type*)t gleich t.get() sein. Ebenso, wenn const T implizit in const element_type* konvertierbar ist, dann muss (const element_type*)ct gleich ct.get() sein.
[edit] Mitgliedertypen
| Mitgliedertyp | Definition |
| element_type | std::remove_reference_t<decltype(*std::declval<T&>())>, der Typ des Objekts, auf das von T verwiesen wird |
[edit] Mitgliederfunktionen
konstruiert ein neues propagate_const(public member function) | |
| (Destruktor) (implizit deklariert) |
destruiert ein propagate_const und zerstört den enthaltenen Zeiger(public member function) |
weist das propagate_const-Objekt zu(public member function) | |
| tauscht den eingehüllten Zeiger (public member function) | |
Observer | |
| gibt einen Zeiger auf das Objekt zurück, auf das der eingehüllte Zeiger zeigt (public member function) | |
| prüft, ob der eingehüllte Zeiger null ist (public member function) | |
| dereferenziert den eingehüllten Zeiger (public member function) | |
| implizite Konvertierungsfunktion zum Zeiger (public member function) | |
[edit] Nicht-Mitglieder-Funktionen
vergleicht mit einem anderen propagate_const, einem anderen Zeiger oder mit nullptr(function template) | |
spezialisiert den swap-Algorithmus(function template) | |
| ruft eine Referenz auf das eingehüllte zeigerähnliche Objekt ab (function template) |
[edit] Hilfsklassen
Hash-Unterstützung für propagate_const(class template specialization) | |
Spezialisierungen der Standard-Vergleichsfunktions-Objekte für propagate_const(class template specialization) |
[edit] Beispiel
#include <experimental/propagate_const> #include <iostream> #include <memory> struct X { void g() const { std::cout << "X::g (const)\n"; } void g() { std::cout << "X::g (non-const)\n"; } }; struct Y { Y() : m_propConstX(std::make_unique<X>()), m_autoPtrX(std::make_unique<X>()) {} void f() const { std::cout << "Y::f (const)\n"; m_propConstX->g(); m_autoPtrX->g(); } void f() { std::cout << "Y::f (non-const)\n"; m_propConstX->g(); m_autoPtrX->g(); } std::experimental::propagate_const<std::unique_ptr<X>> m_propConstX; std::unique_ptr<X> m_autoPtrX; }; int main() { Y y; y.f(); const Y cy; cy.f(); }
Ausgabe
Y::f (non-const) X::g (non-const) X::g (non-const) Y::f (const) X::g (const) X::g (non-const)
[edit] Defect reports
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 3136 | LFTSv2 | bedeutungslose T wie int* const, void*, oder const PtrLike waren erlaubt |
disallowed |