Какова предпочтительная конструкция функции шаблона, требующей значения параметра по умолчанию?

StackOverflow https://stackoverflow.com/questions/1551539

Вопрос

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

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

Это было полезно?

Решение

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

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

Это мощь будет проще заставить клиентов вашей функции просто добавить , (void*)0 если уместно, добавьте много дополнительного механизма для поддержки версии шаблона как с двумя параметрами, так и с тремя параметрами.Однако это зависит от ожидаемого использования.

Другие советы

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

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

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

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

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

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

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

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

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top