テンプレート関数のオーバーロード解決とSFINAE

自作のライブラリを書いていて、SFINAE(Substitution failure is not an error)の詳細が知りたくなった。仕様書を読んだので以下にメモ。

テンプレート関数のオーバーロード解決規則

あるテンプレート関数の呼び出しに対して、オーバーロードされた関数の集合が決定される。それは、

  • 同名の普通の関数
  • 同名のテンプレート関数のうち、テンプレート引数への代入が成功する関数の、その代入後のモノ

を合わせたものになる。「代入後のモノ」は普通の関数と同様に扱われるので、この集合全体が通常のオーバーロード解決にかけられる。
また、

  • テンプレート引数への代入は関数のシグネチャだけを見て行われる
  • 代入に失敗したものは単純に候補に入らないだけなので、エラーにはならない(これがSFINAE)

とのこと。