次のような関数があるとします。
template<typename T> inline
typename std::enable_if<has_member_foo<T>::value,int>::type
foo( T const &t ) {
return t.foo();
}
template<typename T> inline
typename std::enable_if<!has_member_foo<T>::value,int>::type
foo( T const& ) {
return 0;
}
template<typename T> inline
int call_foo( T const &t ) {
return sizeof( T ) + foo( t );
}
これはほとんど問題なく動作しますが、後で特定の型のオーバーロードを追加すると、次のようになります。
inline int foo( std::string const &s ) {
return s.size();
}
の定義の後に追加するとcall_foo()
、オーバーロードは によって使用されませんcall_foo()
。ただし、オーバーロード コードを の定義の前に移動するとcall_foo()
、それが使用されます。
最初のケースでオーバーロードが使用されないのはなぜですか? がコードの他の場所で使用される時点call_foo()
でインスタンス化されるまでに、コンパイラは既にオーバーロードを認識しているのに、なぜそれを使用しないのでしょうか?
私の元のコードには、同様に を使用して保護されfoo()
たテンプレート化されたクラスの静的メンバー関数として関数が含まれていたことに注意してください。そのコード、つまりテンプレート クラスの特殊化は、使用後に提供された場合でも機能しました。foo_traits
enable_if
call_foo()
問題があれば、私はg++
Mac OS X 10.7.4 で 4.6 を使用しています。