Namespaces
Variants
Views
Actions

Difference between revisions of "cpp/experimental/propagate const"

From cppreference.com
m (fmt)
(improved example and made difference to regular (auto) ptr more clearly visible)
Line 119: Line 119:
 
struct X
 
struct X
 
{
 
{
     void g() const { std::cout << "g (const)\n"; }
+
     void g() const { std::cout << "X::g (const)\n"; }
     void g() { std::cout << "g (non-const)\n"; }
+
     void g() { std::cout << "X::g (non-const)\n"; }
 
};
 
};
 
+
 
struct Y
 
struct Y
 
{
 
{
     Y() : m_ptrX(std::make_unique<X>()) {}
+
     Y() : m_propConstX(std::make_unique<X>()), m_autoPtrX(std::make_unique<X>()) {}
 
+
 
     void f() const
 
     void f() const
 
     {
 
     {
         std::cout << "f (const)\n";
+
         std::cout << "Y::f (const)\n";
         m_ptrX->g();
+
         m_propConstX->g();
 +
        m_autoPtrX->g();
 
     }
 
     }
 
+
 
     void f()
 
     void f()
 
     {
 
     {
         std::cout << "f (non-const)\n";
+
         std::cout << "Y::f (non-const)\n";
         m_ptrX->g();
+
         m_propConstX->g();
 +
        m_autoPtrX->g();
 
     }
 
     }
   
+
     std::experimental::propagate_const<std::unique_ptr<X>> m_ptrX;
+
     std::experimental::propagate_const<std::unique_ptr<X>> m_propConstX;
 +
    std::unique_ptr<X> m_autoPtrX;
 
};
 
};
 
      
 
      
Line 151: Line 154:
 
}
 
}
 
|output=
 
|output=
f (non-const)
+
Y::f (non-const)
g (non-const)
+
X::g (non-const)
f (const)
+
X::g (non-const)
g (const)
+
Y::f (const)
 +
X::g (const)
 +
X::g (non-const)
 
}}
 
}}
  

Revision as of 08:19, 8 January 2024

 
 
Experimental
Technical Specification
Filesystem library (filesystem TS)
Library fundamentals (library fundamentals TS)
Library fundamentals 2 (library fundamentals TS v2)
Library fundamentals 3 (library fundamentals TS v3)
Extensions for parallelism (parallelism TS)
Extensions for parallelism 2 (parallelism TS v2)
Extensions for concurrency (concurrency TS)
Extensions for concurrency 2 (concurrency TS v2)
Concepts (concepts TS)
Ranges (ranges TS)
Reflection (reflection TS)
Mathematical special functions (special functions TR)
Experimental Non-TS
Pattern Matching
Linear Algebra
std::execution
Contracts
2D Graphics
 
 
 
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 cv-unqualified pointer-to-object type or a cv-unqualified pointer-like class type, as specified below.

Contents

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, an lvalue of type const T that denotes the same object as t (equivalent to std::as_const(t) since C++17),
  • 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) [edit]
(destructor)
(implicitly declared)
destructs a propagate_const, destroying the contained pointer
(public member function) [edit]
assigns the propagate_const object
(public member function) [edit]
swaps the wrapped pointer
(public member function) [edit]
Observers
returns a pointer to the object pointed to by the wrapped pointer
(public member function) [edit]
checks if the wrapped pointer is null
(public member function) [edit]
dereferences the wrapped pointer
(public member function) [edit]
implicit conversion function to pointer
(public member function) [edit]

Non-member functions

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

Helper classes

hash support for propagate_const
(class template specialization) [edit]
specializations of the standard comparison function objects for propagate_const
(class template specialization) [edit]

Example

#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();
}

Output:

Y::f (non-const)
X::g (non-const)
X::g (non-const)
Y::f (const)
X::g (const)
X::g (non-const)

Defect reports

The following behavior-changing defect reports were applied retroactively to previously published C++ standards.

DR Applied to Behavior as published Correct behavior
LWG 3136 LFTSv2 meaningless T like int* const, void*, or const PtrLike were allowed disallowed