Say I have the following code:
#include <iostream>
#include <functional>
template <int func(int)>
struct S : std::unary_function<int, int>
{
int operator()(int x) const
{
return func(x);
}
};
int foo(int x)
{
return x;
}
int main()
{
S<foo> s;
std::cout << s(42) << std::endl;
}
This works okay as a way of wrapping up a function inside of a functor, which means it can be used in other templated functions (like sort
, for example (assuming the functor had the right signature)). I don't want to create a functor struct for every possible return/argument type (and realistically I can't), and so I tried the following:
template <template <typename R, // Make the return type and argument type template parameters!
typename A> R func(A)>
struct S : std::unary_function<R, A>
{
R operator()(A arg) const
{
return func(arg);
}
};
That didn't work; it gave me compilation errors. So then I tried:
template <typename R, typename A, R func(A)>
struct S : std::unary_function<R, A>
{
R operator()(A arg) const
{
return func(arg);
}
};
Which did work. Unfortunately though, I had to change instantiations of S
to be S<int, int, foo> s;
instead of the nicer S<foo> s;
.
Is it at all possible to templatize the function passed as a template argument such that I can do S<foo> s;
and not hard code the return type and argument type of the function in S
?
My google-foo hasn't been able to find a specific answer.
Edit: Now I'm wondering if this isn't possible. I just thought of "what if foo
is an overloaded function?" There wouldn't be, as far as I know, a way to know which foo
to use when saying S<foo> s;
and thus explicitly stating return/argument type is necessary. Is this correct thinking, and does this mean that the answer to my first question is "No, it's not possible"?