I'm currently working on cleaning up an API full of function templates, and had a strong desire to write the following code.
template <typename T, typename U, typename V>
void doWork(const T& arg1, const U& arg2, V* optionalArg = 0);
When I invoke this template, I would like to do so as follows.
std::string text("hello");
doWork(100, 20.0, &text);
doWork('a', text); // oops!
doWork<char, std::string, void>('a', text); // to verbose!
Unfortunately, the second invocation doesn't compile since the compiler cannot deduce the type of the optional parameter. This is unfortunate, since I really don't care what the parameter type is, but rather that its value is NULL. Also, I'd like to avoid the route of the third invocation since it hampers readability.
This lead me to try to make the template argument V
have a default type, which also doesn't work since you cannot apply a default type to a function template argument (at least using VC++ 9.0).
template <typename T, typename U, typename V = void> // oops!
void doWork(const T& arg1, const U& arg2, V* optionalArg = 0);
My only remaining option is to introduce an overload of doWork
that knows nothing of the template argument V
.
template <typename T, typename U>
void doWork(const T& arg1, const U& arg2)
{
doWork(arg1, arg2, 0);
}
template <typename T, typename U, typename V>
void doWork(const T& arg1, const U& arg2, V* optionalArg);
Is this the best approach to solving this problem? The only drawback I see is that I could potentially introduce many trivial forwarding functions if a function template contains many parameters that have suitable defaults.