Итак, я искал использование абстрактных алгоритмов для повторного использования повторяющихся шаблонов в моем коде. В частности, я хочу определить элемент в массиве узлов, который имеет наибольшую «оценку», определяемую путем оценки сложной функции-члена оценки.
После некоторая помощь Я имеюпридумать (C ++ 17)
template <typename FwdIt, typename Eval, typename Pred = std::less<>>
constexpr FwdIt max_eval_element(FwdIt first, FwdIt last, Eval eval, Pred pred = Pred()) {
FwdIt found = first;
if (first != last) {
auto best = eval(*found);
while (++first != last) {
if (auto const thisVal = eval(*first);
pred(best, thisVal)) {
found = first;
best = thisVal;
}
}
}
return found;
}
Итак, рассмотрим мой класс Node:
class Node {
private:
double val;
public:
Node(double val) noexcept : val(val) {}
[[nodiscard]] auto Score1() const noexcept {
return std::sqrt(std::log(10.0 / val));
}
[[nodiscard]] auto Score2(double other) const noexcept {
return std::sqrt(std::log(other / val));
}
};
и мой массив узлов:
std::array<Node, 100000> nodes;
Я могуВызовите
auto const& Node = *std::max_eval_element(std::cbegin(nodes), std::cend(nodes), std::mem_fn(&Node::Score1));
, но теперь я хочу повторить это для Score2
, где ввод зависит от некоторой локальной переменной ... конечно, я могу написать некоторую лямбда-функцию ... но у нас есть std::bind
для этого, верно? Я знаю, что вы можете вызывать привязку для функции-члена, например
std::bind(this, std::mem_fn(Node::Score1));
Но я хочу наоборот. Что не работает.
auto const& Node = *std::max_eval_element(std::cbegin(nodes), std::cend(nodes), std::bind(std::mem_fn(&Node::Score2), 1.0));
Я попробовал это наоборот, но это также не работает
auto const& Node = *std::max_eval_element(std::cbegin(nodes), std::cend(nodes), std::mem_fn(std::bind(&Node::Score2), 1.0));
Я знаю почему это не такне работает ... функция-член требует указатель объекта в качестве (скрытого) первого аргумента. Но это означало бы, что мы упускаем что-то вроде std::bind_mem_fn
или около того ... У нас было std::bind2nd
в прошлом, но оно было удалено в C ++ 17 ...
Опять же: конечно, яможно использовать лямбду, но учитывая, что существуют такие вещи, как std:mem_fn
и std::bind
, и абстрактные алгоритмы - это хорошо ...
Я что-то упускаю, или это просто отсутствует в стандарте?