これが私自身のコードの例です。構造名の1つから推測できるように、これは置換の失敗はエラーではないという原則に基づいています。構造体has_member_setOrigin
は、の2つのバージョンを定義しますtest
。U
メンバーがいない場合、最初のものは満たすことができませんsetOrigin
。これはテンプレート置換のエラーではないため、存在しないかのように機能します。したがって、ポリモーフィック関数の解決順序はtest(...)
、そうでなければ優先度が低いものを見つけます。次にvalue
、の戻りタイプによって決定されtest
ます。
これに続いて、テンプレートを使用したcallSetOrigin
(のと同等の)2つの定義があります。調べると、最初のテンプレート引数がtrueの場合は定義され、そうでない場合は定義されていないことがわかります。これにより、定義の1つに置換エラーが発生し、1つだけが存続します。equals
enable_if
enable_if
enable_if<...>::type
callSetOrigin
template <typename V>
struct has_member_setOrigin
{
template <typename U, void (U::*)(const Location &)> struct SFINAE {};
template <typename U> static char test(SFINAE<U, &U::setOrigin>*);
template <typename U> static int test(...);
static const bool value = sizeof(test<V>(0)) == sizeof(char);
};
template<typename V>
void callSetOrigin(typename enable_if <has_member_setOrigin<V>::value, V>::type &p, const Location &loc) const
{
p.setOrigin(loc);
}
template<typename V>
void callSetOrigin(typename enable_if <!has_member_setOrigin<V>::value, V>::type &p, const Location &loc) const
{
}
私も定義を提供したことを忘れenable_if
ました:
#ifndef __ENABLE_IF_
#define __ENABLE_IF_
template<bool _Cond, typename _Tp>
struct enable_if
{ };
template<typename _Tp>
struct enable_if<true, _Tp>
{ typedef _Tp type; };
#endif /* __ENABLE_IF_ */