Namespaces
Variants

std:: to_address

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)
ヘッダーで定義 <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) ファンシーポインタ オーバーロード: 式 std:: pointer_traits < Ptr > :: to_address ( p ) が適格な場合、その式の結果を返す。そうでない場合、 std :: to_address ( p. operator - > ( ) ) を返す。
2) 生ポインタのオーバーロード: T が関数型の場合、プログラムは不適格です。それ以外の場合、 p を変更せずに返します。

目次

パラメータ

p - ファンシーポインタまたは生ポインタ

戻り値

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

実装例

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 のファンシーポインタオーバーロードは、 std:: pointer_traits < Ptr > 特殊化を検査します。その特殊化のインスタンス化自体が不適格(通常は element_type が定義できないため)である場合、それは即時コンテキスト外でのハードエラーを引き起こし、プログラムを不適格にします。

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

機能テスト マクロ 標準 機能
__cpp_lib_to_address 201711L (C++20) ポインタを生ポインタに変換するユーティリティ ( 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> の公開静的メンバ関数)