Merge sort implementation using iterators
You should prefer to move values whenever possible.

std::move(begin, mid, std::back_inserter(left));
std::move(mid, end, std::back_inserter(right));

size_t j = 0, k = 0;
auto i = begin;

for (; i != end &amp;&amp; j &lt; left.size() &amp;&amp; k &lt; right.size(); ++i) {
    *i = std::move(comp(left[j], right[k]) ? left[j++] : right[k++]);
}

while (j &lt; left.size()) {
    *(i++) = std::move(left[j++]);
}

while (k &lt; right.size()) {
    *(i++) = std::move(right[k++]);
}


Every call of mergeBack will end up allocating 2 new buffers. You can avoid that by preallocating the secondary buffer and flip flopping between them but that is tricky to do in the recursive version. Which is why I prefer the iterative version that goes bottom up.