std::pointer_traits
来自 cppreference.com
定义在头文件 <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] 成员函数
[静态] |
获取一个可解引用的指针,指向它的参数 (公有静态成员函数) |
2) 为指针类型,T*,提供了特化,它声明了以下成员
[edit] 成员类型
类型 | 定义 |
pointer
|
T* |
element_type
|
T |
difference_type
|
std::ptrdiff_t |
[edit] 成员别名模板
模板 | 定义 |
template< class U > using rebind | U* |
[edit] 成员函数
[静态] |
获取一个可解引用的指针,指向它的参数 (公有静态成员函数) |
[edit] 程序定义的特化的可选成员函数
[静态] (C++20)(可选) |
从一个奇特指针获取一个原始指针(pointer_to 的逆运算)(公有静态成员函数) |
[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);
为用户定义的奇特指针类型提供的特化可能提供一个额外的静态成员函数 |
(自 C++20 起) |
功能测试 宏 | 值 | Std | 功能 |
---|---|---|---|
__cpp_lib_constexpr_memory |
201811L | (C++20) | constexpr 在 std::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) |
提供有关分配器类型的的信息 (类模板) |
(C++11) |
获取对象的实际地址,即使 `&` 运算符被重载了 (函数模板) |