This link doesn't answer my question so I'll ask it here:
Basically I want to write a template function
template <typename Out, typename In>
Out f(In x);
Here I always need to specify Out
when calling f
. I don't want to do it every time, so I basically want
template <typename Out = In, typename In>
Out f(In x);
Which means if I don't specify Out
, it will default to In
. However, this is not possible in C++11.
So my question is, is there any way to achieve the effect:
f(t)
will instantiate f<T,T>(t)
or more generally f<typename SomeThing<T>::type, T>
f<U>(t)
will instantiate f<U, T>(t)
You probably never want to specify In
but rather have it deduced, right?
In this case you need to overload the function:
template <typename Out, In>
Out f(In x);
template <typename T>
T f(T x);
Call it:
f(42);
f<float>(42);
… but unfortunately that’s ambiguous for f<int>(42)
. No matter, we can use SFINAE to disable one of the overloads appropriately:
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);
In order to avoid redundancy in the implementation, let both functions dispatch to a common implementation, f_impl
.
Here’s a working example:
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);
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With