std::experimental::propagate_const

来自cppreference.com
 
 
技术规范
文件系统库 (文件系统 TS)
库基础 (库基础 TS)
库基础 2 (库基础 TS v2)
库基础 3 (库基础 TS v3)
并行扩展 (并行 TS)
并行扩展 2 (并行 TS v2)
并发扩展 (并发 TS)
并发扩展 2 (并发 TS v2)
概念 (概念 TS)
范围 (范围 TS)
反射 (反射 TS)
数学特殊函数 (特殊函数 TR)
 
 
 
template<class T>
class propagate_const;
(库基础 TS v2)

std::experimental::propagate_const 是为指针和仿指针对象传播 const 的包装器。如名所示,在通过 const 访问路径访问时,它把被包装指针当做指向 const 的指针。

若底层的仿指针类型类满足可移动构造 (MoveConstructible) 可移动赋值 (MoveAssignable) 的要求,则该类满足对应概念,但 propagate_const 既非可复制构造 (CopyConstructible) 亦非可复制赋值 (CopyAssignable)

类型要求
-
T 必须是无 cv 限定指向对象的指针类型或按以下方式指定的无 cv 限定的仿指针类类型。

仿指针类型上的要求

T 为类类型,则它必须满足此节中的要求。

给定

  • tT 类型的可修改左值表达式
  • ct ,与 t 指代同一对象的 const T 类型左值(等价于 C++17 起的 std::as_const(t)
  • element_type ,对象类型

下列表达式必须合法并拥有其指定的效果:

表达式 返回类型 前提条件 操作语义
t.get() element_type*
ct.get() element_type*const element_type* t.get() == ct.get()
*t element_type& t.get() != nullptr *t*(t.get()) 指代同一对象
*ct element_type&const element_type& ct.get() != nullptr *ct*(ct.get()) 指代同一对象
t.operator->() element_type* t.get() != nullptr t.operator->() == t.get()
ct.operator->() element_type*const element_type* ct.get() != nullptr ct.operator->() == ct.get()
(bool)t bool (bool)t 等价于 t.get() != nullptr
(bool)ct bool (bool)ct 等价于 ct.get() != nullptr

还有, Tconst T 应当可按语境转换为 bool

另外,若 T 可隐式转换为 element_type* ,则 (element_type*)t 应当等于 t.get() 。类似地,若 const T 可隐式转换为 const element_type* ,则 (const element_type*)ct 应当等于 ct.get()

成员类型

成员类型 定义
element_type std::remove_reference_t<decltype(*std::declval<T&>())>T 所指向对象的类型

成员函数

构造新的 propagate_const
(公开成员函数)
(析构函数)
(隐式声明)
销毁 propagate_const 并销毁所含指针
(公开成员函数)
赋值 propagate_const 对象
(公开成员函数)
交换被包装指针
(公开成员函数)
观察器
返回指向被包装指针所指向对象的指针
(公开成员函数)
检查被包装指针是否为空
(公开成员函数)
解引用被包装指针
(公开成员函数)
到指针的隐式转换函数
(公开成员函数)

非成员函数

与另一 propagate_const 、另一指针,或与 nullptr 比较
(函数模板)
特化 swap 算法
(函数模板)
获取到被包装仿指针对象的引用
(函数模板)

辅助类

propagate_const 的哈希支持
(类模板特化)
标准比较函数对象对 propagate_const 的特化
(类模板特化)

示例

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

输出:

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

缺陷报告

下列更改行为的缺陷报告追溯地应用于以前出版的 C++ 标准。

缺陷报告 应用于 出版时的行为 正确行为
LWG 3136 LFTSv2 曾允许 int* constvoid*const PtrLike 之类的无意义的 T 禁止它们