std::inout_ptr_t
定义于头文件 <memory>
。
template< class Smart, class Pointer, class... Args >
class inout_ptr_t;
inout_ptr_t 用于适配智能指针等类型,这些类型会通过一个 Pointer*
(通常是某个对象类型 T
的 T**
)或 void**
参数来重置所有权。
inout_ptr_t 在构造时捕获额外的参数,为如上所述的外部函数访问提供存储空间,释放所适配 Smart
对象拥有的所有权,并在销毁时用结果和捕获的参数重置所适配的 Smart
对象。
inout_ptr_t 的行为如同它持有以下非静态数据成员
- 一个
Smart&
引用,在构造时绑定到所适配的对象, - 对于
Args...
中的每个T
,一个类型为T
的成员,它是构造时捕获的参数,用于在销毁时进行重置,以及 - 一个适合存储
Pointer
并提供void*
对象的成员子对象,其中Pointer
或void*
对象通常暴露给外部函数用于所有权重置。
如果 Smart
不是指针类型,则最多对所适配对象调用一次 release()
。实现可以在构造函数中,或者在析构函数中重置之前调用 release()
(如果 Pointer
值*不是*空)。
用户可以通过在 Args...
中分别指定对象类型或引用类型来控制每个用于重置的参数是按副本还是按引用捕获。
模板参数
Smart
- 要适配的对象类型(通常是智能指针) Pointer
- 外部函数访问以重置所有权的对象类型(通常是原始指针) Args...
- 用于重置所适配对象的捕获参数的类型
类型要求
- Pointer 必须满足
NullablePointer
的要求。 - 如果
Smart
是 std::shared_ptr 的特化,则程序格式错误。
特化
与标准库中的大多数类模板不同,程序定义的 inout_ptr_t
特化(至少依赖于一个程序定义的类型)不必满足主模板的要求。
此许可证允许程序定义的特化将非标准智能指针中存储的原始指针暴露给外部函数。
成员函数
pub | (构造函数)(C++23) | 构造一个 inout_ptr_t (公共成员函数) |
pub | (析构函数)(C++23) | 在释放其所有权后重置所适配的智能指针 (公共成员函数) |
pub | operator=[已删除](C++23) | inout_ptr_t 不可赋值 (公共成员函数) |
pub | operator Pointer* operator void**(C++23) | 将 inout_ptr_t 转换为输出存储的地址 (公共成员函数) |
非成员函数
pub | inout_ptr(C++23) | 创建一个带有关联的智能指针和重置参数的 inout_ptr_t (函数模板) |
备注
inout_ptr_t 期望外部函数释放由所指向 Pointer
的值表示的所有权,然后重新初始化它。由于此类操作需要唯一的占有权,因此禁止与 std::shared_ptr 一起使用。
inout_ptr_t 的典型用法是通过 std::inout_ptr 创建其临时对象,该对象会立即重置所适配的智能指针。例如,给定一个具有 int foreign_resetter(T**);
声明的设置器函数和一个相应类型的智能指针 std::unique_ptr<T, D> up;
,
if (int ec = foreign_resetter(std::inout_ptr(up))) {
return ec;
}
大致等价于
T *raw_p = up.get();
up.release();
int ec = foreign_resetter(&raw_p);
up.reset(raw_p);
if (ec != 0) {
return ec;
}
不建议创建存储期非自动存储期的 inout_ptr_t 对象,因为此类代码很可能会产生悬空引用并在销毁时导致未定义行为。
捕获的参数通常打包到 std::tuple<Args...>
中。实现可以使用不同的机制来提供它们需要持有的 Pointer
或 void*
对象。
特性测试宏 | 值 | 标准 |
---|---|---|
__cpp_lib_out_ptr | 202106L | (C++23) |