Сравнение 2 значений с использованием шаблона метапрограммирования C ++ - PullRequest
0 голосов
/ 23 ноября 2018

Я хочу использовать функцию по умолчанию в качестве шаблона «Предикат» на случай, если пользователь ее не предоставит.До сих пор я делал что-то вроде:

template<typename T>
struct simple_compare{
    bool operator()(T const& a, T const& b){
        return a > b;
    }
};

template<typename T, typename Predicate=simple_compare<T> >
bool compare(T a, T b, Predicate pred) {
    return pred(a, b);
}

Можно ли это сделать с помощью шаблонного метапрограммирования в C ++ вместо структуры с оператором overloaded ()?

Ответы [ 2 ]

0 голосов
/ 23 ноября 2018

Здесь нет необходимости в метапрограммировании шаблонов.Вы можете просто использовать перегрузку, как показано в ответе Давиде Спатаро, чтобы предоставить версию, которая не принимает предикат и просто вызывает полную версию с предикатом по умолчанию.Или вы можете просто использовать аргумент по умолчанию для вашего предиката:

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);
}
0 голосов
/ 23 ноября 2018

Вам не нужны фантастические шаблоны метапрограммирования.Просто создайте две версии функции шаблона.Тот, у которого нет пользовательского предиката, просто выполнит заданный по умолчанию.

Должно работать что-то вроде следующего:

auto default_pred = [](const auto a, const auto b) {return a > b;};
auto custom_pred  = [](const auto a, const auto b) {return a < b;};


template<typename T, typename Fn >
bool compare2(T a, T b, Fn pred) {
    return pred(a, b);
}

template<typename T >
bool compare2(T a, T b) {
    return default_pred (a, b);
}

int main(){
    cout<<compare2(2, 4)<<endl;
    cout<<compare2(10.2d, 4.5d, custom_pred)<<endl;
   return 0;
}
...