Re-arrange elements of a list without changing the list itself reminds me to something what I would call a proxy.
In this case, a std::vector of list iterators could be used as proxy. I would consider a std::vector as cache friendly (contiguous storage of contents) which may be an additional advantage concerning the performance of sorting.
The proxy vector is sorted with a custom predicate which considers the contents at iterators.
A sample:
#include <algorithm>
#include <iostream>
#include <list>
#include <vector>
int main()
{
using listInt = std::list<int>;
listInt myList{ 1, 5, 3, 2, 4 };
// proxy for sorted access
{ std::vector<listInt::iterator> proxy;
proxy.reserve(myList.size());
for (listInt::iterator iter = myList.begin();
iter != myList.end(); ++iter) {
proxy.push_back(iter);
}
// sort proxy:
std::sort(proxy.begin(), proxy.end(),
[](listInt::iterator iter1, listInt::iterator iter2)
{
return *iter1 < *iter2;
});
// show proxy result
for (listInt::iterator iter : proxy) {
std::cout << ' ' << *iter;
}
std::cout << '\n';
}
std::cout << "The list (still in original order):\n";
for (int value : myList) {
std::cout << ' ' << value;
}
std::cout << '\n';
}
Output:
1 2 3 4 5
The list (still in original order):
1 5 3 2 4
Live Demo on coliru
Please note, as long as none of the list elements is deleted the list iterators are stable. (Get pointer to node in std::list or std::forward_list)
It might be questionable whether to store iterators instead of the values (which are plain int) is an advantage in any way. However, the size of iterator probably won't change if the list would contain elements of a "heavier" type where a deep copy would have a significant impact or even prohibited.
Googling a bit afterwards, I found this:
SO: Sort by proxy (or: sort one container by the contents of another) in C++
which might be related (IMHO).