Здесь нет необходимости в метапрограммировании шаблонов.Вы можете просто использовать перегрузку, как показано в ответе Давиде Спатаро, чтобы предоставить версию, которая не принимает предикат и просто вызывает полную версию с предикатом по умолчанию.Или вы можете просто использовать аргумент по умолчанию для вашего предиката:
template <typename T, typename Predicate = simple_compare<T>>
bool compare(T a, T b, Predicate pred = {}) {
return pred(a, b);
}
Если вы просто хотите универсальный функтор, который вызывает оператор>, тогда вы также можете просто сделать operator ()
шаблоном вместо функтора.введите сам и позвольте точным типам для сравнения определить из вызова:
struct simple_compare {
template <typename A, typename B>
bool operator()(A const& a, B const& b) const {
return a > b;
}
};
template <typename T, typename Predicate = simple_compare>
bool compare(T a, T b, Predicate pred = {}) {
return pred(a, b);
}
Кроме того, стандартная библиотека уже предоставляет стандартных функторов для вызова всех видов операторов.Таким образом, вместо того, чтобы бросить свой собственный, вы можете просто использовать std::greater<T>
или std::greater<void>
в вашем примере.Кроме того, я предполагаю, что нет реальной необходимости требовать, чтобы ваши аргументы были копируемыми и имели такой же тип:
template <typename A, typename B, typename Predicate = std::greater<void>>
bool compare(A const& a, B const& b, Predicate pred = {}) {
return pred(a, b);
}