C++ insertion sort implementation
Small nitpicks

The for loop can be started from 1, as the iteration with 0 doesn't actually do anything.
Prefer to reduce the scope of variables if possible. This allows better reasoning for the compiler/optimizer, and makes the code more readable because the variable declaration is nearer to the actual usage.
The check arr[index_sorted] &gt;= 0 in the while loop should probably be index_sorted &gt;= 0u (after all, Element might not be comparable to integers), but this is true in all cases (-1 for an unsigned integer type is equal to that type's maximum value). However, even checking this becomes unnecessary if the first iteration starts at 1.
The array elements could possibly be moved to their new locations (this might improve performance in some cases).


template&lt;typename Element&gt;
void insertion_sort(Element arr[], size_t size) {
    for (auto index = 1u; index &lt; size; ++index) {
        auto temp = std::move(arr[index]);
        auto index_sorted = index - 1;
        while (arr[index_sorted] &gt; temp) {
            arr[index_sorted + 1] = std::move(arr[index_sorted--]);
        }
        arr[index_sorted + 1] = std::move(temp);
    }
}


Technically, the size of the array could be deduced automatically by taking a reference (though it has an ugly syntax). However, by taking an explicit size parameter one can sort a partial array, so I'd prefer the flexibility of this approach.