# std::experimental::propagate_const

From cppreference.com
< cpp‎ | experimental

Defined in header `<experimental/propagate_const>` |  |
template<class T> class propagate_const; |  | (library fundamentals TS v2)

`std::experimental::propagate_const` is a const-propagating wrapper for pointers and pointer-like objects. It treats the wrapped pointer as a pointer to `const` when accessed through a `const` access path, hence the name.

The class satisfies the requirements of MoveConstructible and MoveAssignable if the underlying pointer-like type satisfies the corresponding requirement, but `propagate_const` is neither CopyConstructible nor CopyAssignable.

Type requirements
- `T` must be an object pointer type or a pointer-like class type, as specified below. The program is ill-formed if `T` is an array type, reference type, pointer to function type, pointer to (possibly cv-qualified) `void`, or if decltype(*std::declval<T&>()) is not an lvalue reference type.

### Requirements on pointer-like class types

If `T` is a class type, it must satisfy the requirements in this subsection.

Given

- `t`, a modifiable lvalue expression of type `T`
- `ct`, a `const T&` bound to `T`
- `element_type`, an object type

The following expressions must be valid and have their specified effects:

Expression | Return type | Pre-conditions | Operational semantics
--- | --- | --- | ---
t.get() | `element_type*` |  |
ct.get() | `element_type*` or `const element_type*` |  | t.get() == ct.get()
*t | `element_type&` | t.get() != nullptr | `*t` refers to the same object as `*(t.get())`
*ct | `element_type&` or `const element_type&` | ct.get() != nullptr | `*ct` refers to the same object as `*(ct.get())`
t.operator->() | `element_type*` | t.get() != nullptr | t.operator->() == t.get()
ct.operator->() | `element_type*` or `const element_type*` | ct.get() != nullptr | ct.operator->() == ct.get()
(bool)t | `bool` |  | (bool)t is equivalent to t.get() != nullptr
(bool)ct | `bool` |  | (bool)ct is equivalent to ct.get() != nullptr

Further, `T` and `const T` shall be contextually convertible to `bool`.

In addition, if `T` is implicitly convertible to `element_type*`, then `(element_type*)t` shall be equal to `t.get()`. Similarly, if `const T` is implicitly convertible to `const element_type*`, then `(const element_type*)ct` shall be equal to `ct.get()`.

### Member types

Member type | Definition
element_type | std::remove_reference_t<decltype(*std::declval<T&>())>, the type of the object pointed to by `T`

### Member functions

(constructor) | constructs a new `propagate_const` (public member function)
(destructor) (implicitly declared) | destructs an `propagate_const`, destroying the contained pointer (public member function)
operator= | assigns the `propagate_const` object (public member function)
swap | swaps the wrapped pointer (public member function)

##### Observers

get | returns a pointer to the object pointed to by the wrapped pointer (public member function)
operator bool | checks if the wrapped pointer is null (public member function)
operator*operator-> | dereferences the wrapped pointer (public member function)
operator element_type*operator const element_type* | implicit conversion function to pointer (public member function)

### Non-member functions

operator==operator!=operator<operator<=operator>operator>= | compares to another `propagate_const`, another pointer, or with nullptr (function template)
std::experimental::swap(std::experimental::propagate_const) | specializes the `swap` algorithm (function template)
get_underlying | Retrieves a reference to the wrapped pointer-like object (function template)

### Helper classes

std::hash<std::experimental::propagate_const> | hash support for `propagate_const` (class template specialization)

std::equal_to<std::experimental::propagate_const>std::not_equal_to<std::experimental::propagate_const>std::less<std::experimental::propagate_const>std::greater<std::experimental::propagate_const>std::less_equal<std::experimental::propagate_const>std::greater_equal<std::experimental::propagate_const>

Specializations of the standard comparison function objects for `propagate_const`
(class template specialization)

### Example

Run this code

    #include <iostream>
    #include <memory>
    #include <experimental/propagate_const>

    struct X
    {
        void g() const { std::cout << "g (const)\n"; }
        void g() { std::cout << "g (non-const)\n"; }
    };

    struct Y
    {
        Y() : m_ptrX(std::make_unique<X>()) { }

        void f() const
        {
            std::cout << "f (const)\n";
            m_ptrX->g();
        }

        void f()
        {
            std::cout << "f (non-const)\n";
            m_ptrX->g();
        }

        std::experimental::propagate_const<std::unique_ptr<X>> m_ptrX;
    };

    int main()
    {
        Y y;
        y.f();

        const Y cy;
        cy.f();
    }

Output:

    f (non-const)
    g (non-const)
    f (const)
    g (const)

Retrieved from "https://en.cppreference.com/mwiki/index.php?title=cpp/experimental/propagate_const&oldid=103762"