I have been playing around with variadic templates in the new c++ standard and came up with a map function (headers + using decs excluded):
template<typename T>
T square(T i)
{
return i * i;
}
template <typename T, typename... Ts>
const tuple<Ts...> map(const T f, const Ts...args)
{
return make_tuple(f(args)...);
}
int main(int c, char *argv[])
{
tuple<int, int> t;
int (*fp) (int) = square;
t = map(fp, 6, 8);
cout <<get<0>(t) <<endl;
cout <<get<1>(t) <<endl;
return 0;
}
Which works. As long as all the arguments are the same type for map. If I change the main to use a slightly more general form:
tuple<int, float> t;
t = map(square, 6, 8.0f);
gcc 4.4 reports:
In function ‘int main(int, char**)’:
error: no matching function for call to ‘map(<unresolved overloaded function type>, int, float)’
Any ideas how to make this work?
First, you can't pass around an unresolved function template as a pointer (or template parameter), you can only pass around instances of it. What that means is that your template's first argument is being passed as an int (*)(int)
in this example, and it cannot call the float (*)(float)
instantiation. I'm not sure of the best way to fix that, but anyway it's not technically what you asked about.
I don't have a compiler to test this on, but I think if you use std::function
to infer the types that the function you are passing in wants, you might be able to cast the parameters to the function. Like this:
template<typename T, typename Ts...>
tuple<Ts...> map(std::function<T (T)> const &f, Ts... args) {
return make_tuple(static_cast<Ts>(f(static_cast<T>(args)))...);
}
See, I think you need to cast both the parameter (as a T
) and the return type (as a Ts
) for the function since it seems some implicit conversion rules are not working inside this template.
If my syntax doesn't work (it probably doesn't, the ...
s are tricky when you don't have a compiler for them), it might be possible that you could rewrite this as a much more verbose function which unpacks each Ts
before calling the function, and then builds up a tuple as it goes. I'm not sure if that is really necessary, but my feeling is that compiler support for all of the ...
unpacking is a little spotty right now, so even if you come up with something that should work, I wouldn't be surprised if your compiler couldn't handle it.
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