Reputation: 2121
It seems I should to use function as a template argument, but it cannot be done in such way.
The header file looks like this:
foo_out_type foo(foo_in_type input);
baz_out_type bar(bar_in_type input);
template<typename T_IN, typename T_OUT>
void do_list(const vector<T_IN>& input,
vector<T_OUT>& output);
// I want to specialize the template code at compile time
// So the users don't need to compile the code everytime
template<>
void do_list<foo_in_type, foo_out_type>(const vector<foo_in_type>& input,
vector<foo_out_type>& output);
template<>
void do_list<bar_in_type, bar_out_type>(const vector<bar_in_type>& input,
vector<bar_out_type>& output);
The implementation file looks like this:
template<typename T_IN, typename T_OUT, typename T_FUNC>
void __do_list_impl__(const vector<T_IN>& input,
vector<T_OUT>& output)
{
for (size_t i=0; i<input.size(); i++)
output.push_back(T_FUNC(input[i]));
}
template<>
void do_list<foo_in_type, foo_out_type>(const vector<foo_in_type>& input,
vector<foo_out_type>& output)
{
__do_list_impl__<foo_in_type, foo_out_type, do_foo>(input, output);
}
template<>
void do_list<bar_in_type, bar_out_type>(const vector<bar_in_type>& input,
vector<bar_out_type>& output)
{
__do_list_impl__<bar_in_type, bar_out_type, do_bar>(input, output);
}
The key is: I don't want to write the implementation several times, as the actual code is much more complex than this. However, the function cannot be passed as an template argument.
So, how should I work around this?
Upvotes: 2
Views: 108
Reputation: 1062
You just have to use functor instead of a function.
Instead of declaring your body function as:
T_OUT do_foo(T_IN& input) {
//your job
}
declare it as an object type:
class do_foo {
public:
T_OUT operator()(T_IN& input) {
//place your job code here
}
};
Then change your do_list implementation from:
template<typename T_IN, typename T_OUT, typename T_FUNC>
void __do_list_impl__(const vector<T_IN>& input,
vector<T_OUT>& output)
{
for (size_t i=0; i<input.size(); i++)
output.push_back(T_FUNC(input[i]));
}
to:
template<typename T_IN, typename T_OUT, typename T_FUNCTOR>
void __do_list_impl__(const vector<T_IN>& input,
vector<T_OUT>& output)
{
T_FUNCTOR myFunctor;
for (size_t i=0; i<input.size(); i++)
output.push_back(myFunctor(input[i]));
}
Obviously create a new class also for the "do_bar" function
Upvotes: 1
Reputation: 1968
Assuming you only have a small number of specialized versions of do_list<...>()
...
In your header:
do_list<...>()
to call different
non-template helper functions do_list_impl1()
, do_list_impl2()
, ...do_list_impl1()
, do_list_impl2()
, ...In your implementation file:
__do_list_impl__()
do_list_impl1()
et al to just call __do_list_impl__()
with appropriate template arguments.Upvotes: 0