命名空间
变体
操作

std::pointer_traits

来自 cppreference.cn
< cpp‎ | 内存
 
 
内存管理库
(仅作说明*)
未初始化内存算法
(C++17)
(C++17)
(C++17)
受约束的未初始化
内存算法
C 库

分配器
内存资源
垃圾回收支持
(C++11)(直到 C++23)
(C++11)(直到 C++23)
(C++11)(直到 C++23)
(C++11)(直到 C++23)
(C++11)(直到 C++23)
(C++11)(直到 C++23)
未初始化存储
(直到 C++20*)
(直到 C++20*)
显式生命周期管理
 
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 定义
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 定义
template< class U > using rebind U*

[编辑] 成员函数

[静态]
获取指向其参数的可解引用指针
(公共静态成员函数) [编辑]

[编辑] 程序定义特化的可选成员函数

[静态] (C++20)(可选)
从花式指针获取原始指针(pointer_to 的逆操作)
(公共静态成员函数) [编辑]

[编辑] 注意

rebind 成员模板别名使得给定指向 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
{
    // Predefine a memory block
    struct block;
 
    // Define a pointer to a memory block from the kind of pointer Ptr s
    // If Ptr is any kind of T*, block_ptr_t is block*
    // If Ptr is smart_ptr<T>, block_ptr_t is 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;
    // The type of bl1.free_blocks is BlockList<int*>:: block*
 
    BlockList<std::shared_ptr<char>> bl2;
    // The type of bl2.free_blocks is
    // 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)
获取对象的实际地址,即使 & 运算符被重载
(函数模板) [编辑]