C++ Heap Sort Implementation Just checking if I could still do it:

#include &lt;iostream&gt;
#include &lt;algorithm&gt;

std::size_t getParent(std::size_t n)
{
    return (n - 1) / 2;
}

template&lt;typename I&gt;
void heapify(I begin, I end)
{
    std::size_t size    = std::distance(begin, end);
    for(std::size_t loop = 1;loop &lt; size; ++loop)
    {
        std::size_t current = loop;
        std::size_t parent  = getParent(current);
        while(current != 0 &amp;&amp; *(begin + parent) &lt; *(begin + current))
        {
            std::swap(*(begin + parent), *(begin + current));
            current = parent;
            parent  = getParent(current);
        }
    }
}

template&lt;typename I&gt;
void heapPop(I begin, I end)
{
    I   last = end - 1;
    std::swap(*begin, *last);

    std::size_t size    = std::distance(begin, last);
    std::size_t current = 0;
    while(current &lt; size)
    {
        std::size_t child1  = current * 2 + 1;
        std::size_t child2  = current * 2 + 2;
        std::size_t goodChild = current;

        if (child2 &lt; size)
        {
            goodChild   = (*(begin + child1) &gt; *(begin + child2)) ? child1 : child2;
        }
        else if (child1 &lt; size)
        {
            goodChild   = child1;
        }
        if (*(begin + current) &lt; *(begin + goodChild))
        {
            std::swap(*(begin + current), *(begin + goodChild));
            current = goodChild;
            continue;
        }
        break;
    }
}


template&lt;typename I&gt;
void heap_sort(I begin, I end)
{
    heapify(begin, end);
    while(begin != end)
    {
        heapPop(begin, end);
        --end;
    }
}

int main()
{
    int  data[] = {6,5,3,1,8,7,2,4};
    heap_sort(std::begin(data), std::end(data));
    std::copy(std::begin(data), std::end(data), std::ostream_iterator&lt;int&gt;(std::cout, ", "));
    std::cout &lt;&lt; "\n";
}
The heapify and parentfunctions can be avoided:

You just need the sinking logic that you already implemented. But instead of having current always starting at 0 you can set it as a parameter:

template&lt;typename I&gt;
void sink(I begin, I end, std::size_t index)
{

    std::size_t size = std::distance(begin, end);
    std::size_t current = index;
    while (current &lt; size)
    {
        std::size_t child1 = current * 2 + 1;
        std::size_t child2 = current * 2 + 2;
        std::size_t goodChild = current;

        if (child2 &lt; size)
        {
            goodChild = (*(begin + child1) &gt; *(begin + child2)) ? child1 : child2;
        }
        else if (child1 &lt; size)
        {
            goodChild = child1;
        }
        if (*(begin + current) &lt; *(begin + goodChild))
        {
            std::swap(*(begin + current), *(begin + goodChild));
            current = goodChild;
            continue;
        }
        break;
    }
}


Due to the fact that the elements  are leafs you can ignore them, so you just need to apply sink 
 
times to build the heap: 

template&lt;typename I&gt;
void heap_sort(I begin, I end)
{
    std::size_t size = std::distance(begin, end);
    for (int i = size / 2 - 1; i &gt; -1; --i) 
    {
        sink(begin, end, i);
    }
    while (begin != --end) 
    {
        std::swap(*begin, *end);
        sink(begin, end, 0);
    }
}


Alternative sink implementation: 

IMO this implementation is more concise:

template&lt;typename I&gt;
void sink(I begin, I end, std::size_t index)
{

    std::size_t size = std::distance(begin, end);
    std::size_t current = index;
    std::size_t child;

    std::less&lt;decltype(*begin)&gt; less;

    while ((child = 2 * current + 1) &lt; size)
    {
        I itr_child   = begin + child;
        I itr_current = begin + current;

        if(child &lt; size - 1 
            &amp;&amp; less(*itr_child, *(itr_child + 1))
        {
            ++itr_child;
        }

        if (!less(*itr_current, *itr_child))
        {
            break;
        }
        std::swap(*itr_current, *itr_child);
        current = child;
    }
}