Я реализую вариационные функции min/max. Цель состоит в том, чтобы использовать время компиляции, известное количество аргументов и выполнить развернутую оценку (избегать циклов времени выполнения). Текущее состояние кода выглядит следующим образом (представление min-max похоже)
#include <iostream>
using namespace std;
template<typename T>
T vmin(T val1, T val2)
{
return val1 < val2 ? val1 : val2;
}
template<typename T, typename... Ts>
T vmin(T val1, T val2, Ts&&... vs)
{
return val1 < val2 ?
vmin(val1, std::forward<Ts>(vs)...) :
vmin(val2, std::forward<Ts>(vs)...);
}
int main()
{
cout << vmin(3, 2, 1, 2, 5) << endl;
cout << vmin(3., 1.2, 1.3, 2., 5.2) << endl;
return 0;
}
Теперь работает, но у меня есть несколько вопросов/проблем:
-
невариантная перегрузка должна принимать свои аргументы по значению. Если я попробую передать другие типы ссылок, я получаю следующие результаты:
- универсальные ссылки
&&
→ ошибка компиляции - const ссылки
const&
→ OK - простые ссылки
&
→ ошибка компиляции
Теперь я знаю, что шаблоны функций смешались с шаблонами, но есть ли какие-либо конкретные ноу-хау для этого микса? Какой тип аргументов я должен выбрать?
- универсальные ссылки
-
Не будет ли расширение пакета параметров достаточным? Действительно ли мне нужно перенаправить свои аргументы на рекурсивный вызов?
-
Является ли эта функция лучше реализована, когда она завершена внутри структуры и отображается как статическая функция-член. Будет ли возможность частичной специализации купить мне что-нибудь?
-
Есть ли более эффективная/эффективная реализация/дизайн для версии функции? (в частности, мне интересно, будет ли версия
constexpr
соответствовать эффективности метапрограммирования шаблона)