Is this an efficient way to implement Merge Sort in C++? I am studying C++ and I wrote the following Merge Sort algorithm. I need some comments from skilled C++ programmers to understand where it can be improved, in terms of execution time, memory usage and "style". I am aware this question is rather generic but really, any comment is appreciated, even more if well motivated.

Is it ok to return a new vector by value every time the recursive function is called?

template&lt;typename T&gt;
vector&lt;T&gt; mergeSort(vector&lt;T&gt; const &amp;v, unsigned long s, unsigned long e){
    if (e-s == 0) return vector&lt;T&gt;{}; //return empty vector
    else if (e-s == 1) return vector&lt;T&gt;{v[s]}; //return vector with single element
    else{
        unsigned long mid = (e+s)/2;
        vector&lt;T&gt; v1 = mergeSort(v, s, mid);
        vector&lt;T&gt; v2 = mergeSort(v, mid, e);
        vector&lt;T&gt; vr (e-s); // allocate the space needed

        typename vector&lt;T&gt;::iterator p1 = v1.begin();
        typename vector&lt;T&gt;::iterator p2 = v2.begin();
        typename vector&lt;T&gt;::iterator pr = vr.begin();

        while (p1 != v1.end() &amp;&amp; p2 != v2.end()) *pr++ = (*p1 &lt; *p2) ? *p1++ : *p2++;
        while (p1 != v1.end()) *pr++ = *p1++;
        while (p2 != v2.end()) *pr++ = *p2++;

        return vr;
    }
}

int main(int argc, const char * argv[]) {
    vector&lt;int&gt; v {2, 7, -1, 4, 2, 6, -10};    
    vector&lt;int&gt; vsorted = mergeSort(v, 0, v.size());
    return 0;
}
A single most important property of a merge sort is stability: equal elements maintain their relative order. This

    *pr++ = (*p1 &lt; *p2) ? *p1++ : *p2++;


is a very typical mistake. In case *p1 == *p2, the element will be merged from the second array. Stability is lost. Not a problem for integers, of course, but keep in mind. The fix is simple:

    *pr++ = (*p2 &lt; *p1) ? *p2++ : *p1++;