std::pointer_traits

来自cppreference.com
< cpp‎ | memory
 
 
动态内存管理
未初始化内存算法
受约束的未初始化内存算法
分配器
垃圾收集器支持
(C++11)(C++23 前)
(C++11)(C++23 前)
(C++11)(C++23 前)
(C++11)(C++23 前)
(C++11)(C++23 前)
(C++11)(C++23 前)



 
std::pointer_traits
成员函数
 
在标头 <memory> 定义
template< class Ptr >
struct pointer_traits;
(1) (C++11 起)
template< class T >
struct pointer_traits<T*>;
(2) (C++11 起)

pointer_traits 类模板提供访问指针式类型(缀饰指针,如 boost::interprocess::offset_ptr)的某些属性的标准化方法。标准模板 std::allocator_traits 依靠 pointer_traits 确定多种分配器 (Allocator) 所要求的 typedef 的默认行为。

1) 非特化 pointer_traits 条件性地声明下列成员:

/*element-type-of*/<Ptr>

  • Ptr::element_type,若它存在;
  • 否则若 Ptr 为类模板特化 Template<T, Args...> 而其中 Args... 为零或更多个类型实参,则为 T
  • 否则不定义。

/*element-type-of*/<Ptr> 不被定义,则主模板无此页面中所指定的成员。

成员类型

类型 定义
pointer Ptr
element_type /*element-type-of*/<Ptr>
difference_type 若存在则为 Ptr::difference_type,否则为 std::ptrdiff_t

成员别名模板

模板 定义
template <class U> using rebind 若存在则为 Ptr::rebind<U>,否则若 Ptr 是模板特化 Template<T, Args...> 则为 Template<U, Args...>

成员函数

[静态]
获得指向其实参的可解引用指针
(公开静态成员函数)
2) 为指针类型 T* 提供的特化,它声明下列成员:

成员类型

类型 定义
pointer T*
element_type T
difference_type std::ptrdiff_t

成员别名模版

模板 定义
template <class U> using rebind U*

成员函数

[静态]
获得指向其实参的可解引用指针
(公开静态成员函数)

程序定义特化的可选成员函数

[静态] (C++20)(可选)
从缀饰指针获得裸指针( pointer_to 的反函数)
(公开静态成员函数)

注解

重绑定成员模板别名,使得可以由指向 T 的类指针类型,获取指向 U 的相同类指针类型。例如,

using another_pointer = std::pointer_traits<std::shared_ptr<int>>::rebind<double>;
static_assert(std::is_same<another_pointer, std::shared_ptr<double>>::value);

对用户定义指针类型的特化可提供额外的静态成员函数 to_address 以定制 std::to_address 的行为。

(C++20 起)
功能特性测试 标准 功能特性
__cpp_lib_constexpr_memory 201811L (C++20) std::pointer_traits 中的 constexpr

示例

#include <iostream>
#include <memory>
 
template<class Ptr>
struct BlockList
{
   // 预定义内存块
   struct block;
 
   // 从指针 Ptr 的种类定义指向内存块的指针
   // 若 Ptr 是任何 T* 类型,则 block_ptr_t 为 block*
   // 若 Ptr 是 smart_ptr<T>,则 block_ptr_t 为 smart_ptr<block>
   using block_ptr_t = typename std::pointer_traits<Ptr>::template rebind<block>;
 
   struct block
   {
       std::size_t size{};
       block_ptr_t next_block{};
   }; 
 
   block_ptr_t free_blocks;
}; 
 
int main()
{
    [[maybe_unused]]
    BlockList<int*> bl1;
    // bl1.free_blocks 的类型是 BlockList<int*>::block*
 
    BlockList<std::shared_ptr<char>> bl2;
    // bl2.free_blocks 的类型是 std::shared_ptr<BlockList<std::shared_ptr<char>>::block>
    std::cout << bl2.free_blocks.use_count() << '\n';
}

输出:

​0​

缺陷报告

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

缺陷报告 应用于 出版时的行为 正确行为
LWG 3545 C++11 主模板在 element_type 非法时导致硬错误 使之为 SFINAE 友好

参阅

提供关于分配器类型的信息
(类模板)
(C++11)
获得对象的实际地址,即使其重载了 & 运算符
(函数模板)