template< class T >
class propagate_const;
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.
T
must be cv-unqualified pointer-to-object type or a cv-unqualified pointer-like class type, as specified below. [edit] 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() != nullptrFurther, 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().
#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)[edit] 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 meaninglessT
like int* const, void*, or const PtrLike were allowed disallowed
RetroSearch is an open source project built by @garambo | Open a GitHub Issue
Search and Browse the WWW like it's 1997 | Search results from DuckDuckGo
HTML:
3.2
| Encoding:
UTF-8
| Version:
0.7.4