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).