Find element yielding the largest value w.r.t. custom function I made a function to find the element that yields the largest value when put into a custom functor.

I think this is missing from the STL. I can think of three ways to do this in STL:


Transform the container by the functor. Find the maximum in the transformed version. Take the corresponding element from the original container.
Transform the container to an iterable of std::pairs containing the iterators to the original values and the corresponding functor result value. Write a custom comparison function which compares the .second of the pairs. Find max among the pairs with std::max_element. Take .first of the resulting iterator.
Use a custom comparator functor in std::max_element (return f(lhs) &lt; f(rhs)). 


The first two are really cumbersome and the third calls the functor twice as many times as necessary. Hence this:

template&lt;typename Iterable, typename UnaryFun&gt;
auto maxElementBy(Iterable const&amp; iterable, UnaryFun criterion)
    -&gt; decltype(std::begin(iterable))
{
    typedef decltype(criterion(*std::begin(iterable))) CriterionResult;

    auto itCurrent = std::begin(iterable);
    auto itEnd = std::end(iterable);

    if (itCurrent == itEnd)
    {
        return itEnd;
    }

    CriterionResult bestValue = criterion(*itCurrent);
    auto itBest = itCurrent;
    ++itCurrent;

    for (; itCurrent != itEnd; ++itCurrent)
    {
        CriterionResult currentValue = criterion(*itCurrent);
        if (bestValue &lt; currentValue)
        {
            itBest = itCurrent;
            bestValue = std::move(currentValue);
        }
    }
    return itBest;
}


Any suggestions?
Setting aside the std::accumulate discussion, I have one recommendation. The signature

template&lt;typename Iterator, typename UnaryFun&gt;
auto maxElementBy(Iterator first, Iterator last, UnaryFun criterion)
    -&gt; Iterator


seems to be more flexible. It allows partial ranges, and seems more in line with the std design approach.