В настоящее время я работаю над очисткой API, полного шаблонов функций, и очень хотел написать следующий код.
template <typename T, typename U, typename V>
void doWork(const T& arg1, const U& arg2, V* optionalArg = 0);
Когда я вызываю этот шаблон, я хотел бы сделать это следующим образом.
std::string text("hello");
doWork(100, 20.0, &text);
doWork('a', text); // oops!
doWork<char, std::string, void>('a', text); // to verbose!
К сожалению, второй вызов не компилируется, так как компилятор не может определить тип необязательного параметра. Это прискорбно, поскольку мне действительно все равно, что это за тип параметра, а его значение равно NULL. Кроме того, я бы хотел избежать маршрута третьего вызова, так как он ухудшает читабельность.
Это привело меня к попытке сделать аргумент шаблона V
типом по умолчанию, который также не работает, поскольку вы не можете применить тип по умолчанию к аргументу шаблона функции (по крайней мере, с помощью VC ++ 9.0).
template <typename T, typename U, typename V = void> // oops!
void doWork(const T& arg1, const U& arg2, V* optionalArg = 0);
Мой единственный оставшийся вариант - ввести перегрузку doWork
, которая ничего не знает о аргументе шаблона 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);
Это лучший подход к решению этой проблемы? Единственный недостаток, который я вижу, состоит в том, что я мог бы потенциально ввести много тривиальных функций пересылки, если шаблон функции содержит много параметров, которые имеют подходящие значения по умолчанию.