Namespaces
Variants

std:: pointer_traits

From cppreference.net
Memory management library
( exposition only* )
Allocators
Uninitialized memory algorithms
Constrained uninitialized memory algorithms
Memory resources
Uninitialized storage (until C++20)
( until C++20* )
( until C++20* )
( until C++20* )

Garbage collector support (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)
(C++11) (until C++23)
std::pointer_traits
Member functions
(C++20) (optional)
ヘッダーで定義 <memory>
template < class Ptr >
struct pointer_traits ;
(1) (C++11以降)
template < class T >
struct pointer_traits < T * > ;
(2) (C++11以降)

pointer_traits クラステンプレートは、ポインタ様の型( fancy pointers 、例えば 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... > である場合は T Args... は0個以上の型引数);
  • それ以外の場合、定義されない。

/*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... >

メンバ関数

[static]
引数へのデリファレンス可能なポインタを取得する
(公開静的メンバ関数)
2) ポインタ型に対して特殊化が提供されており、 T * 以下のメンバーを宣言します:

メンバー型

定義
pointer T *
element_type T
difference_type std::ptrdiff_t

メンバーエイリアステンプレート

テンプレート 定義
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);

ユーザー定義のファンシーポインタ型に対する特殊化は、追加の静的メンバー関数 to_address を提供して、 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
{
    // メモリブロックの事前定義
    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++規格に対して遡及的に適用されました。

DR 適用対象 公開時の動作 正しい動作
LWG 3545 C++11 プライマリテンプレートは element_type が無効な場合にハードエラーを引き起こした SFINAEフレンドリーに変更

関連項目

アロケータ型に関する情報を提供する
(クラステンプレート)
(C++11)
オブジェクトの実際のアドレスを取得する( & 演算子がオーバーロードされている場合でも)
(関数テンプレート)