の 2 番目のテンプレート パラメーターは、戻り値の型としてのみ表示されるgetため、推測できません。たとえば、呼び出した場合、その呼び出しは正しい専門化に解決されます。get<Tag1>()get<Tag1, double>get<Tag1, int>get<Tag1, double>()
getただし、2 つのテンプレート パラメーターを持つ関数テンプレートになりたくないのではないかと思います。戻り値の型は、おそらく最初のパラメーターの関数であることを意図しています。getそのため、次のように宣言することをお勧めします。
namespace result_of {
template<typename T>
struct get;
}
template<typename T>
typename result_of::get<T>::type get();
whereresult_of::getは、期待される結果の型を計算するメタ関数になります。関数テンプレートを特殊化するのではなく、物事を簡単にするためgetに、すべての卵をresult_of::getバスケットに入れます。
namespace result_of {
template<typename T>
struct get;
}
template<typename T>
typename result_of::get<T>::type get()
{ return result_of::get<T>::apply(); }
namespace result_of {
template<>
struct get<Tag1> {
typedef double type;
static type apply()
{ return 1.3; }
};
template<>
struct get<Tag2> {
typedef const char* type;
static type apply()
{ return "hello"; }
};
}
一般に、関数テンプレートよりもクラス テンプレートを特殊化する方がはるかに一般的であり、関数テンプレートを特殊化する必要があるように見える場合は、関数テンプレートがその実装を完全にクラス テンプレートに委任できるようにすることで、より簡単になることがよくあります。