Computing average without overflows and with half-decent precision
First, having a forward-iterator is good enough, don't ask for more. Yes, it might mean you have to go over the range twice (once to measure its size), but that's a minor irritant.
Just please, verify it is a forward-iterator like this:

std::forward_iterator_tag = std::iterator_traits&lt;ForwardIt&gt;::iterator_category{};

Use the right loop for the job. It's more readable, and more concise.
Mark any variable you can const to help comprehension and error-checking.
Next, you really have to improve your overflow-handling, as res += static_cast&lt;long double&gt;(accumulator) / static_cast&lt;long double&gt;(size); might loose a small amount of precision.
Stay in the integer-realm by adding / subtracting enough multiples of size to change the sign of accumulator.
Don't cast to long double unless you can guarantee perfect accuracy.
You can easily supplant the builtin with a bit of logic:
Test the sign of accumulate and depending on the result check whether MAXVALUE - accumulate &gt; *first or MINVALUE - accumulate &lt; *first.
Not sure whether the compiler can optimize that as well as the builtin though...
Consider whether making it SFINAE-friendly by avoiding hard errors might be worth the more verbose error-messages.


Modified code:

#include &lt;cstdint&gt;
#include &lt;iterator&gt;
#include &lt;type_traits&gt;
#include &lt;limits&gt;

template&lt;typename ForwardIt&gt;
long double average(ForwardIt first, ForwardIt last)
{
    static_assert(std::is_integral&lt;typename std::iterator_traits&lt;ForwardIt&gt;::value_type&gt;(),
        "average only available for built-in integer types");
    std::forward_iterator_tag = std::iterator_traits&lt;ForwardIt&gt;::iterator_category();

    const auto size = std::distance(first, last);
    if (!size) return 0;

    std::intmax_t accumulator = 0;
    long double res = 0;
    do {
        using snl = std::numeric_limits&lt;decltype(accumulator)&gt;;
        if (accumulator &lt; 0 &amp;&amp; snl::min() - accumulator &gt; *first) {
            res += accumulator / size - 1;
            accumulator = accumulator % size + size;
        } else if (accumulator &gt; 0 &amp;&amp; snl::max() - accumulator &lt; *first) {
            res += accumulator / size + 1;
            accumulator = accumulator % size - size;
        }
        accumulator += *first;
    } while (++first != last);
    res += accumulator / size;
    res += static_cast&lt;decltype(res)&gt;(accumulator % size) / size;
    return res;
}