对码当歌,猿生几何?

std::experimental::propagate_const

From cppreference.com
 
 
Technical specifications
Filesystem library (filesystem TS)
Library fundamentals (library fundamentals TS)
Library fundamentals 2 (library fundamentals 2 TS)
Extensions for parallelism (parallelism TS)
Extensions for concurrency (concurrency TS)
Concepts (concepts TS)
Ranges (ranges TS)
Special mathematical functions (special math TR)
 
 
 
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 concept, 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

constructs a new propagate_const
(public member function)
(destructor)
(implicitly declared)
destructs an propagate_const, destroying the contained pointer
(public member function)
assigns the propagate_const object
(public member function)
swaps the wrapped pointer
(public member function)
Observers
returns a pointer to the object pointed to by the wrapped pointer
(public member function)
checks if the wrapped pointer is null
(public member function)
dereferences the wrapped pointer
(public member function)
implicit conversion function to pointer
(public member function)

Non-member functions

compares to another propagate_const, another pointer, or with nullptr
(function template)
specializes the swap algorithm
(function template)
Retrieves a reference to the wrapped pointer-like object
(function template)

Helper classes

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

Example

#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)