名前空間
変種
操作

std::addressof

提供: cppreference.com
< cpp‎ | memory
 
 
 
動的メモリ管理
未初期化記憶域
(C++17)
ガベージコレクションサポート
その他
(C++20)
addressof
(C++11)
(C++11)
C のライブラリ
低水準のメモリ管理
 
ヘッダ <memory> で定義
(1)
template< class T >
T* addressof(T& arg) noexcept;
(C++11およびそれ以降)
(C++17以前)
template< class T >
constexpr T* addressof(T& arg) noexcept;
(C++17およびそれ以降)
template <class T>
const T* addressof(const T&&) = delete;
(2) (C++17およびそれ以降)
1) オーバーロードされた operator& が存在していても、オブジェクトまたは関数 arg の実際のアドレスを取得します。
2) const 右辺値のアドレスを取得することを防ぐために、右辺値のオーバーロードは削除されています。

E が左辺値の定数部分式であれば、式 std::addressof(E)定数部分式です。

(C++17およびそれ以降)

目次

[編集] 引数

arg - 左辺値のオブジェクトまたは関数

[編集] 戻り値

arg を指すポインタ。

[編集] 実装例

template< class T >
T* addressof(T& arg) 
{
    return reinterpret_cast<T*>(
               &const_cast<char&>(
                  reinterpret_cast<const volatile char&>(arg)));
}

ノート: 上記の実装は過度に単純化されておりconstexpr ではありません (コンパイラのサポートが必要になります)。

[編集]

operator& はポインタへのポインタを取得するためにポインタラッパークラスに対してオーバーロードされているかもしれません。

#include <iostream>
#include <memory>
 
template<class T>
struct Ptr {
    T* pad; // add pad to show difference between 'this' and 'data'
    T* data;
    Ptr(T* arg) : pad(nullptr), data(arg) 
    {
        std::cout << "Ctor this = " << this << std::endl;
    }
 
    ~Ptr() { delete data; }
    T** operator&() { return &data; }
};
 
template<class T>
void f(Ptr<T>* p) 
{
    std::cout << "Ptr   overload called with p = " << p << '\n';
}
 
void f(int** p) 
{
    std::cout << "int** overload called with p = " << p << '\n';
}
 
int main() 
{
    Ptr<int> p(new int(42));
    f(&p);                 // calls int** overload
    f(std::addressof(p));  // calls Ptr<int>* overload, (= this)
}

出力例:

Ctor this = 0x7fff59ae6e88
int** overload called with p = 0x7fff59ae6e90
Ptr   overload called with p = 0x7fff59ae6e88

[編集] 関連項目

デフォルトのアロケータ
(クラステンプレート) [edit]
[static]
引数を指す逆参照可能なポインタを取得します
(std::pointer_traitsのパブリック静的メンバ関数) [edit]