更新: C ++ 11では、のstd::addressof
代わりにを使用できますboost::addressof
。
最初にBoostからコードをコピーして、コンパイラーがビットを回避するようにします。
template<class T>
struct addr_impl_ref
{
T & v_;
inline addr_impl_ref( T & v ): v_( v ) {}
inline operator T& () const { return v_; }
private:
addr_impl_ref & operator=(const addr_impl_ref &);
};
template<class T>
struct addressof_impl
{
static inline T * f( T & v, long ) {
return reinterpret_cast<T*>(
&const_cast<char&>(reinterpret_cast<const volatile char &>(v)));
}
static inline T * f( T * v, int ) { return v; }
};
template<class T>
T * addressof( T & v ) {
return addressof_impl<T>::f( addr_impl_ref<T>( v ), 0 );
}
関数への参照を渡すとどうなりますか?
注:addressof
関数へのポインターでは使用できません
C ++では、if void func();
が宣言されている場合、func
は引数を取らず、結果を返さない関数への参照です。関数へのこの参照は、関数へのポインタに簡単に変換できます@Konstantin
-from:13.3.3.2によると両方ともT &
、T *
関数と区別できません。1つ目はID変換で、2つ目は「完全一致」ランク(13.3.3.1.1表9)を持つ関数からポインターへの変換です。
関数 pass through への参照addr_impl_ref
は、の選択に対するオーバーロードの解決にあいまいさがあり、これは最初であり、(Integral Conversion)に昇格できるf
ダミー引数のおかげで解決されます。0
int
long
したがって、単純にポインタを返します。
変換演算子を使用して型を渡すとどうなりますか?
変換演算子がa T*
を生成する場合、あいまいさf(T&,long)
があります。f(T*,int)
最初の引数で変換演算子が呼び出されている間、2番目の引数には統合プロモーションが必要です(@litbに感謝)
それがaddr_impl_ref
始まるときです。C++標準では、変換シーケンスには最大で1つのユーザー定義の変換が含まれるように規定されています。型をラップしaddr_impl_ref
、変換シーケンスの使用を強制することにより、型に付属する変換演算子をすべて「無効」にします。
したがって、f(T&,long)
過負荷が選択されます(および統合プロモーションが実行されます)。
他のタイプの場合はどうなりますか?
したがって、f(T&,long)
タイプがT*
パラメータと一致しないため、オーバーロードが選択されます。
注:Borlandの互換性に関するファイル内のコメントから、配列はポインターに減衰しませんが、参照によって渡されます。
このオーバーロードで何が起こりますか?
operator&
型が過負荷になっている可能性があるため、型には適用しないでください。
reinterpret_cast
この作業に使用できる標準が保証されています(@Matteo Italiaの回答:5.2.10 / 10を参照)。
Boostは、コンパイラの警告を回避するための修飾子const
といくつかの便利な機能を追加しvolatile
ます(そしてconst_cast
それらを削除するために適切にa を使用します)。
- キャスト
T&
するchar const volatile&
- ストリップ
const
とvolatile
&
オペレーターに住所を申請する
- にキャストバックする
T*
const
/ volatile
ジャグリングは黒魔術のビットであり、それは(かなり4つのオーバーロードを提供するよりも)作業を簡素化しません。以来という注意T
修飾されていない、私たちが渡した場合はghost const&
、その後T*
であるghost const*
ので、修飾子は本当に失われていません、。
編集:ポインターオーバーロードは関数へのポインターに使用されます。上記の説明を多少修正しました。なぜそれが必要なのかはまだわかりません。
次のideone出力は、これをいくらか要約しています。