命名空间
变体
操作

std::pointer_traits

来自 cppreference.com
< cpp‎ | memory
 
 
动态内存管理
未初始化内存算法
约束的未初始化内存算法
分配器
垃圾回收支持
(C++11)(until C++23)
(C++11)(until C++23)
(C++11)(until C++23)
(C++11)(until C++23)
(C++11)(until C++23)
(C++11)(until 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 所需的各种类型定义的默认值。

1) 非特化 pointer_traits 有条件地声明以下成员

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

  • Ptr::element_type(如果存在);
  • 否则,如果 Ptr 是类模板特化 Template<T, Args...>,则为 T,其中 Args... 是零个或多个类型参数;
  • 否则,未定义。

如果 /*element-type-of*/<Ptr> 未定义,则主模板在本页面中没有指定任何成员。

内容

[edit] 成员类型

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

[edit] 成员别名模板

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

[edit] 成员函数

[静态]
获取一个可解引用的指针,指向它的参数
(公有静态成员函数) [edit]
2) 为指针类型,T*,提供了特化,它声明了以下成员

[edit] 成员类型

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

[edit] 成员别名模板

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

[edit] 成员函数

[静态]
获取一个可解引用的指针,指向它的参数
(公有静态成员函数) [edit]

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

[静态] (C++20)(可选)
从一个奇特指针获取一个原始指针(pointer_to 的逆运算)
(公有静态成员函数) [edit]

[edit] 注释

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 起)
功能测试 Std 功能
__cpp_lib_constexpr_memory 201811L (C++20) constexprstd::pointer_traits

[edit] 示例

#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​

[edit] 缺陷报告

以下行为变更缺陷报告被追溯应用到以前发布的 C++ 标准。

DR 应用于 已发布的行为 正确行为
LWG 3545 C++11 主模板在 element_type 无效时导致硬错误 使其对 SFINAE 友好

[edit] 另请参见

提供有关分配器类型的的信息
(类模板) [编辑]
(C++11)
获取对象的实际地址,即使 `&` 运算符被重载了
(函数模板) [编辑]