Каков предпочтительный дизайн функции шаблона, которая требует значения параметра по умолчанию? - PullRequest
1 голос
/ 11 октября 2009

В настоящее время я работаю над очисткой 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);

Это лучший подход к решению этой проблемы? Единственный недостаток, который я вижу, состоит в том, что я мог бы потенциально ввести много тривиальных функций пересылки, если шаблон функции содержит много параметров, которые имеют подходящие значения по умолчанию.

Ответы [ 3 ]

5 голосов
/ 11 октября 2009

Я думаю, что ваша функция переадресации является совершенно подходящим решением, хотя в вашем решении вам не придется явно указывать параметры шаблона? (0 - целочисленная константа, которую можно охватить любым типом V*.) Также doWord против doWork?

Как правило, старайтесь избегать необязательных параметров, если они не дают очень сильных результатов.

Возможно, * * * * * * * * * * * * * * * * * * * * * * * - * * * - * - * * - * * * - * * * - * * * - * * * - * * * * - * * * * - * * * * * Способнее * * * * * * * * * * * * * * * * * * * * * - это просто добавить , (void*)0, если он важен, чем добавить к очень дополнительному механизму для поддержки как двухпараметрической, так и трехпараметрической версии шаблона. Хотя это зависит от ожидаемого использования.

2 голосов
/ 12 октября 2009

С точки зрения клиентского кода, если у него нет третьего параметра, зачем его изобретать?

Так что, если вы стремитесь к удобству использования и читабельности, я согласен с вашим методом обертки: он имеет смысл, и обертка , которую вы написали, отвечает за достойное значение третьего параметра you необходимо.

Кроме того, при необходимости можно использовать разные значения по умолчанию для разных специализаций.

0 голосов
/ 11 октября 2009

Одна из возможностей - переупорядочить аргументы шаблона, поэтому необязательный на первом месте.

template <typename V, typename T, typename U>
void doWork(const T& arg1, const U& arg2, V* optionalArg = 0);

doWork<void>('a', text); 

Пересылка тоже выглядит нормально.

Но, похоже, аргументы и шаблоны по умолчанию не совпадают.

...