I define a set of function templates:
template < typename type >
void foo ( type object )
{
// foo the object
}
template < typename type >
void bar ( type object )
{
// bar the object
}
template < typename type >
void baz ( type object )
{
// baz the object
}
Now I want to define a function template which takes a pointer to any of the functions from the above.
template < /* ??? */ , typename T , typename... TT >
void for_each ( T parameter , TT... other parameters )
{
// process the first parameter using the function pointer defined by the first template parameter
// recursice call to for_each
}
What is the correct way to declare the first template parameter?
P.S. I do know that there is a workaround to wrap the first three functions each in a class and make them static. I just want to know if there is a straight way to solve the problem.
Template template parameters can only be class templates, not function templates, so you'd have to wrap the function template in a class template:
template<typename T>
struct foo_wrap {
static constexpr void (*fn)(T) = &foo<T>;
};
In C++1y you might consider streamlining this with a generic lambda, although that would be a function parameter, not a template parameter:
for_each(..., [](auto t) { foo(t); }, ...);
struct foo_overload_set_t {
template<typename... Ts>
auto operator()(Ts&&... ts) const
-> decltype( foo(std::forward<Ts>(ts)...) ) {
return ( foo(std::forward<Ts>(ts)...) );
}
};
static const foo_overload_set_t foo_overload_set;
now foo_overload_set is a single object which can be treated like a function, and when invoked does overload resolution on the function foo based off the passed in parameters.
Ie, foo( a, b, c, d, e ) runs the same code and gives the exact same result as foo_overload_set( a, b, c, d, e ) for any set of arguments.
But foo_overload_set is an object, while foo is an indeterminate set of functions created on the fly based off parameters used to call it.
We can pass said object to your for_each:
template<typename OverloadSet>
void for_each( OverloadSet ) {} // do nothing
template < typename OverloadSet , typename T , typename... TT >
void for_each ( OverloadSet overload, T&& parameter , TT&&... other_parameters )
{
overload( std::forward<T>(parameter) );
for_each( overload, std::forward<TT>(other_parameters)... );
}
invoked like:
for_each( foo_overload_set, a, b, c, d, e );
which proceeds to call foo on a, then on b, then on c, etc.
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