Reputation: 9816
This is probably a newbie question but I thought it might be interesting. Let's say I have this function:
template <typename First, typename... T>
int ComputeSomething(const First& f, const T&... t);
I would like to write a second function that calls the one above in the general case, but converts the arguments when First
and T
are of type float
, i.e., it calls a Convert
function on each argument:
long Convert(float f);
template <typename First, typename... T>
int MyFun(const First& f, const T&... t) {
return ComputeSomething(f, t...);
}
// This is what I would like:
int MyFun(const float& f, const float& t...) {
return ComputeSomething(Convert(f), Convert(t)...);
}
How can I achieve that?
Upvotes: 1
Views: 139
Reputation: 48447
Add a transparent Convert
overload, so that non-floats are bypassed (that is, you can have mixed types of arguments):
template <typename First, typename... T>
int ComputeSomething(const First& f, const T&... t);
long Convert(float f);
// Transparent converter
template <typename T>
T&& Convert(T&& t) { return std::forward<T>(t); }
template <typename First, typename... Ts>
int MyFun(const First& f, const Ts&... t)
{
return ComputeSomething(Convert(f), Convert(t)...);
}
Upvotes: 3
Reputation: 56863
You could use a helper to test if all types are float
:
#include <type_traits>
template< typename... > struct typelist {};
template< typename T, typename... Ts >
using is_all_same = std::is_same< typelist< T, Ts... >,
typelist< Ts..., T > >;
long Convert(float f);
template <typename First, typename... T>
typename std::enable_if< !is_all_same< float, First, T... >::value, int >::type
MyFun(const First& f, const T&... t) {
return ComputeSomething(f, t...);
}
template <typename First, typename... T>
typename std::enable_if< is_all_same< float, First, T... >::value, int >::type
MyFun(const First& f, const T&... t) {
return ComputeSomething(Convert(f), Convert(t)...);
}
The helper is quite generic and can be used in other contexts as well.
EDIT: I replaced std::tuple
with typelist
, although the tuple would never be instantiated in the above context. I was just using it for convenience, but since some people think it is too much overhead, I edited the answer.
Upvotes: 2