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