Вы чрезмерно ограничиваете оба аргумента и пытаетесь использовать шаблонное вычитание и неявное преобразование одновременно для второго, что не может работать.Отказ от этого и, при необходимости, использование SFINAE, делает все работает правильно, более эффективно и гибко:
using std::begin;
using std::end;
template <class Range, class F>
auto transform(Range&& range, F f)
noexcept(noexcept(std::transform(begin(range), end(range), begin(range), f)))
-> decltype(std::transform(begin(range), end(range), begin(range), f))
{ return std::transform(begin(range), end(range), begin(range), f); }
Да, объект-функция копируется.Если вы не хотите этого, просто передайте std::reference_wrapper
, используя std::ref
, как для алгоритмов стандартной библиотеки.