При выделении памяти в куче перед этими 8 байтами выделяется место под служебную информацию. Из-за этого такие большие накладные расходы в 100 мегабайт.
Для оптимального расходования памяти нужно использовать кастомный аллокатор, который будет выделять память большими кусками сразу, а потом уже использовать этот кусок для кучи маленьких объектов.
но меня смущает вызов 2 дополнительных функций в шаблоне
Функции заинлайнятся, за производительность тут переживать не стоит.
У вас немного разные алгоритмы. В шаблоне никто не запрещает вам пройтись циклом по итераторам и посчитать среднее тем же способом, что и в первом варианте.
Использование stl-функций предпочтительнее своего велосипеда. Читать код легче. Я увидел accumulate и сразу подумал о свёртке. А в первый пример пришлось вчитываться. К тому же он ещё и не оптимальный - ведь деление можно вынести из цикла.
Данный вариант с шаблоном намного гибче - его можно использовать с любым контейнером, который реализует итератор.