std::pointer_traits
From 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 は、Allocator によって要求される様々な typedef のデフォルトを決定するために pointer_traits に依存しています。
1) 非特殊化された
pointer_traits は、以下のメンバーを条件付きで宣言します。Let /*element-type-of*/<Ptr> を
- 存在する場合は Ptr::element_type;
- それ以外の場合、
Ptrがクラステンプレート特殊化 Template<T, Args...> である場合(ここで Args... は0個以上の型引数)、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...> |
[編集] メンバー関数
| [static] |
引数への逆参照可能なポインターを取得する (public static member function) |
2) ポインター型 T* の特殊化が提供され、以下のメンバーを宣言します。
[編集] メンバー型
| 型 | 定義 |
pointer
|
T* |
element_type
|
T |
difference_type
|
std::ptrdiff_t |
[編集] メンバーエイリアステンプレート
| Template | 定義 |
| template< class U > using rebind | U* |
[編集] メンバー関数
| [static] |
引数への逆参照可能なポインターを取得する (public static member function) |
[編集] プログラム定義の特殊化のオプションのメンバー関数
| [static] (C++20)(optional) |
ファンシーポインターから生ポインターを取得する(pointer_to の逆)(public static member function) |
[編集] 備考
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);
|
ユーザー定義のファンシーポインター型に対する特殊化は、std::to_address の動作をカスタマイズするために、追加の静的メンバー関数 |
(C++20以降) |
| 機能テストマクロ | 値 | 規格 | 機能 |
|---|---|---|---|
__cpp_lib_constexpr_memory |
201811L |
(C++20) | constexpr in std::pointer_traits |
[編集] 例
このコードを実行
#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++標準に遡って適用されました。
| DR | 適用対象 | 公開された動作 | 正しい動作 |
|---|---|---|---|
| LWG 3545 | C++11 | element_type が無効な場合、プライマリテンプレートがハードエラーを引き起こした |
SFINAEフレンドリーにされた |
[編集] 関連項目
| (C++11) |
アロケータ型に関する情報を提供します (クラステンプレート) |
| (C++11) |
& 演算子がオーバーロードされていても、オブジェクトの実際のアドレスを取得します(関数テンプレート) |