Шаблонная функция поэлементного сравнения для контейнеров - PullRequest
0 голосов
/ 06 марта 2020

Я пытаюсь написать шаблонную функцию поэлементного сравнения для контейнеров следующим образом:

struct identity {
  template <typename U>
  constexpr auto operator()(U&& v) const noexcept
      -> decltype(std::forward<U>(v)) {
    return std::forward<U>(v);
  }
};

template <typename Comparator, typename Container>
constexpr auto elem_compare(const Container& a, const Container& b) noexcept {
  Container elemCompare{a};
  std::transform(a.cbegin(), a.cend(), b.cbegin(), elemCompare.begin(),
                 Comparator{});
  return std::all_of(elemCompare.cbegin(), elemCompare.cend(), identity{});
}

При попытке использовать это как в

  std::array a{-0.3, 0.1, -0.5};
  std::array b{0.0, 0.0, 0.0};
  auto isLessEqual = elem_compare<std::less_equal>(a, b);

Я получаю ошибку компилятора сообщая мне, что вывод / подстановка аргументов шаблона не удалась.

Что мне нужно сделать, чтобы компилятор выводил аргументы шаблона на elem_compare правильно?


Редактировать: это будет лучшая реализация? Как я мог еще улучшить его?

template <template <typename> typename Comparator, typename Container>
constexpr bool elem_compare(
    const Container& a,
    const Container& b,
    const Comparator<typename Container::value_type>& comparator =
        Comparator<typename Container::value_type>{}) noexcept {
  auto a_iterator = std::cbegin(a);
  auto b_iterator = std::cbegin(b);
  for (; a_iterator != a.cend() && b_iterator != b.cend();
       ++a_iterator, ++b_iterator) {
    if (!comparator(*a_iterator, *b_iterator))
      return false;
  }
  return true;
}
...