名前空間
変種
操作

std::to_address

From cppreference.com
< cpp‎ | memory
 
 
メモリ管理ライブラリ
(説明用*)
未初期化メモリのアルゴリズム
(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まで*)
明示的な生存期間管理
 
ヘッダ <memory> で定義
template< class Ptr >
constexpr auto to_address( const Ptr& p ) noexcept;
(1) (C++20以降)
template< class T >
constexpr T* to_address( T* p ) noexcept;
(2) (C++20以降)

p が指すオブジェクトへの参照を形成せずに、p によって表されるアドレスを取得します。

1) Fancy pointer オーバーロード: 式 std::pointer_traits<Ptr>::to_address(p) が整形式の場合、その式の結果を返します。そうでない場合、std::to_address(p.operator->()) を返します。
2) Raw pointer オーバーロード: T が関数型の場合、プログラムは不適格です。そうでない場合、p を変更せずに返します。

目次

[編集] パラメーター

p - fancy または raw ポインター

[編集] 戻り値

p と同じアドレスを表す raw ポインター。

[編集] 可能な実装

template<class T>
constexpr T* to_address(T* p) noexcept
{
    static_assert(!std::is_function_v<T>);
    return p;
}
 
template<class T>
constexpr auto to_address(const T& p) noexcept
{
    if constexpr (requires{ std::pointer_traits<T>::to_address(p); })
        return std::pointer_traits<T>::to_address(p);
    else
        return std::to_address(p.operator->());
}

[編集] 備考

std::to_address は、p がオブジェクトが構築されていないストレージを参照している場合でも使用できます。この場合、std::addressof(*p) のパラメーターがバインドする有効なオブジェクトがないため、std::addressof は使用できません。

std::to_address の fancy pointer オーバーロードは、std::pointer_traits<Ptr> 特殊化を検査します。この特殊化のインスタンス化自体が不適格な場合(通常、element_type を定義できないため)、即時のコンテキスト外でハードエラーが発生し、プログラムが不適格になります。

std::to_address は、std::contiguous_iterator を満たすイテレーターにも使用できます。

機能テストマクロ 規格 機能
__cpp_lib_to_address 201711L (C++20) ポインターを raw ポインターに変換するユーティリティ(std::to_address

[編集]

#include <memory>
 
template<class A>
auto allocator_new(A& a)
{
    auto p = a.allocate(1);
    try
    {
        std::allocator_traits<A>::construct(a, std::to_address(p));
    }
    catch (...)
    {
        a.deallocate(p, 1);
        throw;
    }
    return p;
}
 
template<class A>
void allocator_delete(A& a, typename std::allocator_traits<A>::pointer p)
{
    std::allocator_traits<A>::destroy(a, std::to_address(p));
    a.deallocate(p, 1);
}
 
int main()
{
    std::allocator<int> a;
    auto p = allocator_new(a);
    allocator_delete(a, p);
}

[編集] 関連項目

ポインタライクな型に関する情報を提供します
(クラステンプレート) [編集]
[static] (C++20)(optional)
ファンシーポインターから生ポインターを取得する(pointer_to の逆)
std::pointer_traits<Ptr> の public static メンバー関数) [編集]
English 日本語 中文(简体) 中文(繁體)