アドレス値の取得(Address Of)
編集

意図 編集

&演算子がオーバーロードされたクラスのアドレス取得

別名 編集

動機 編集

C++では、&演算子のオーバーロードが可能である。そのため、そういったオブジェクトに対して&演算子を使用しても、実際のオブジェクトのアドレスが取得できない場合がある。そういったクラスを実装することに対しての議論の余地はあるものの、言語仕様的には可能となっている。このパターンは、そういったクラスのアドレスを取得するためのものである。

下の例では、&演算子がprivateとなっているため、コンパイルに失敗する。また、privateでないにしても、double型からポインタ型に変換することも可能ではないし意味のないものである。

class nonaddressable 
{
public:
    typedef double useless_type;
private:
    useless_type operator&() const;
};
 
int main()
{
  nonaddressable na;
  nonaddressable * naptr = &na; // Compiler error here.
}

解法とサンプルコード 編集

Address-of パターンでは、キャストを連続して使用することでオブジェクトのアドレスを取得する。

template <class T>
T * addressof(T & v)
{
  return reinterpret_cast<T *>(& const_cast<char&>(reinterpret_cast<const volatile char &>(v)));
}
int main()
{
  nonaddressable na;
  nonaddressable * naptr = addressof(na); // No more compiler error.
}

既知の利用 編集

  • Boost addressof utility
  • C++11からは、この関数はstd::addressofとして<memory> ヘッダに含まれている。
  • C++17以降、このテンプレートはconstexprとしてマークされています。

関連するイディオム 編集

References 編集