- 910 名前:デフォルトの名無しさん mailto:sage [2010/03/14(日) 23:18:09 ]
- >>905
まず、has_swap<T>はどんな型にも適合するのでhas_swap<hoge>の実体化が行われる。 コンパイラはhas_swap<hoge>の基底クラスとして、has_swap_impl<hoge, void>を実体化しようとする。 なお、has_swap_implの第2テンプレート引数は省略されているのでデフォルトのvoidが使われる。 has_swap_impl<hoge, void>を実体化しようとした際に、 コンパイラはまず、より特殊化されたバージョンである 14行目のバージョンに適合するかのチェックを行う。 ここで問題は、typename has_swap_helper<T, &T::swap>::type が void と一致するかどうか。 ・メンバ関数としてvoid T::swap(T&)が存在するならば、has_swap_helperのテンプレート引数が確定し、 かつ4行目のテンプレートに適合するので、4行目のテンプレートが実体化され、voidになる。 すると、has_swap_impl<hoge, void>は14行目のバージョンに適合する。 ・void T::swap(T&)が存在しないならば、適合するhas_swap_helperは「存在しない」。 通常の感覚ならばエラーになりそうだが、 SFINAEの規則によってエラーとはならず、 単に14行目のバージョンが候補から除外される。 コンパイラは次に9行目のバージョンの実体化を行おうとする。 9行目は何でも適合するので、has_swap_impl<fuga, void>は9行目のバージョンに適合する。 あくまでもhas_swap_impl<hoge, void>がどれにマッチするかが問題なので、 たとえば6行目のtypedefをintに変えたりするとダメ (その場合、9行目を class U = int にすればいい)
|

|