あなたはおそらく特定したくないでしょうIn
が、むしろそれを推測していますよね?
この場合、関数をオーバーロードする必要があります。
template <typename Out, In>
Out f(In x);
template <typename T>
T f(T x);
あれを呼べ:
f(42);
f<float>(42);
…しかし、残念ながらそれはあいまいですf<int>(42)
。いずれにせよ、SFINAE を使用してオーバーロードの 1 つを適切に無効にすることができます。
template <
typename Out,
typename In,
typename = typename std::enable_if<not std::is_same<Out, In>::value>::type
>
Out f(In x);
template <typename T>
T f(T x);
実装の冗長性を避けるために、両方の関数を共通の実装にディスパッチさせf_impl
ます。
これが実際の例です:
template <typename Out, typename In>
Out f_impl(In x) {
std::cout << "f<" << typeid(Out).name() <<
", " << typeid(In).name() <<
">(" << x << ")\n";
return x;
}
template <
typename Out,
typename In,
typename = typename std::enable_if<not std::is_same<Out, In>::value>::type
>
Out f(In x) {
std::cout << "f<Out, In>(x):\t ";
return f_impl<Out, In>(x);
}
template <typename T>
T f(T x) {
std::cout << "f<T>(x):\t ";
return f_impl<T, T>(x);
}
int main() {
f(42);
f<float>(42);
f<int>(42);
}