Namensräume
Varianten
Aktionen

std::experimental::propagate_const

Von cppreference.com
 
 
 
 
 
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 Typ T,
  • ct, ein lvalue vom Typ const T, der dasselbe Objekt wie t bezeichnet (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) [edit]
(Destruktor)
(implizit deklariert)
destruiert ein propagate_const und zerstört den enthaltenen Zeiger
(public member function) [edit]
weist das propagate_const-Objekt zu
(public member function) [edit]
tauscht den eingehüllten Zeiger
(public member function) [edit]
Observer
gibt einen Zeiger auf das Objekt zurück, auf das der eingehüllte Zeiger zeigt
(public member function) [edit]
prüft, ob der eingehüllte Zeiger null ist
(public member function) [edit]
dereferenziert den eingehüllten Zeiger
(public member function) [edit]
implizite Konvertierungsfunktion zum Zeiger
(public member function) [edit]

[edit] Nicht-Mitglieder-Funktionen

vergleicht mit einem anderen propagate_const, einem anderen Zeiger oder mit nullptr
(function template) [edit]
spezialisiert den swap-Algorithmus
(function template) [edit]
ruft eine Referenz auf das eingehüllte zeigerähnliche Objekt ab
(function template) [edit]

[edit] Hilfsklassen

Hash-Unterstützung für propagate_const
(class template specialization) [edit]
Spezialisierungen der Standard-Vergleichsfunktions-Objekte für propagate_const
(class template specialization) [edit]

[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