std:: addressof
|
|
|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
ヘッダー
<memory>
で定義
|
||
|
template
<
class
T
>
T * addressof ( T & arg ) noexcept ; |
(1) |
(C++11以降)
(C++17以降 constexpr) |
|
template
<
class
T
>
const T * addressof ( const T && ) = delete ; |
(2) | (C++11以降) |
|
式
|
(C++17以降) |
目次 |
パラメータ
| arg | - | 左辺値オブジェクトまたは関数 |
戻り値
arg へのポインタ。
実装例
以下の実装は constexpr ではありません。なぜなら reinterpret_cast は定数式で使用できないためです。コンパイラのサポートが必要です(下記参照)。
template<class T> typename std::enable_if<std::is_object<T>::value, T*>::type addressof(T& arg) noexcept { return reinterpret_cast<T*>( &const_cast<char&>( reinterpret_cast<const volatile char&>(arg))); } template<class T> typename std::enable_if<!std::is_object<T>::value, T*>::type addressof(T& arg) noexcept { return &arg; } |
この関数の正しい実装にはコンパイラのサポートが必要です: GNU libstdc++ , LLVM libc++ , Microsoft STL .
注記
| 機能テスト マクロ | 値 | 標準 | 機能 |
|---|---|---|---|
__cpp_lib_addressof_constexpr
|
201603L
|
(C++17) |
constexpr
std::addressof
|
constexpr
for
addressof
は
LWG2296
によって追加され、MSVC STLはこの変更を欠陥報告としてC++14モードに適用しています。
組み込みの
operator
&
の使用が、たとえオーバーロードされていない場合でも、
argument-dependent lookup
によって不適格となる特殊なケースが存在します。そのような場合、
std::addressof
を代わりに使用できます。
template<class T> struct holder { T t; }; struct incomp; int main() { holder<holder<incomp>*> x{}; // &x; // エラー: 実引数依存の名前探索が holder<incomp> のインスタンス化を試みる std::addressof(x); // OK }
例
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 << '\n'; } ~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
欠陥報告
以下の動作変更の欠陥報告書は、以前に公開されたC++規格に対して遡及的に適用されました。
| DR | 適用対象 | 公開時の動作 | 正しい動作 |
|---|---|---|---|
| LWG 2598 | C++11 | std :: addressof < const T > が右値のアドレスを取得可能だった | 削除されたオーバーロードによって禁止 |
関連項目
|
デフォルトアロケータ
(クラステンプレート) |
|
|
[static]
|
引数へのデリファレンス可能なポインタを取得する
(
std::pointer_traits<Ptr>
の
公開静的メンバ関数)
|