Sorting function that also works with containers having only forward iterators
The loop

for(size_t i = 0; i &lt; n/2; ++i)
    ++mid;


may and should be replaced with std::advance(mid, n/2)

To answer your question on better ways of finding the midpoint, I don't think it is worthy: it complicates the logic, while the amount of calculation remains the same.
A condition if(*first1 &lt; *first2) breaks the stability of merge sort. This way, if two elements compared equal, the one from the second list would output first. Very standard mistake. To fix, either compare for &lt;=, or change the order:

if (*first2 &lt; *first1) {
    *out = *first2;
    ++first2;
} else {
    *out = *first1;
    ++first1;