I was trying to resort a set when i realised that it was impossible to resort a set and i had to create a new set and have a custom sort function to resort it . I researched onl
Your two sets have different types (the compare function is part of the type definition).
Since std::set
does not provide a constructor or assignment operator for different compare functions, you have to either initialize the new set with an iterator pair to your first set or std::copy
over the elements.
That is:
set<Point2D,p2d_sortby_y> p2d_set2 { std::begin(p2d_set), std::end(p2d_set) };
or
set<Point2D,p2d_sortby_y> p2d_set2;
std::copy(std::begin(p2d_set), std::end(p2d_set), std::inserter(p2d_set2));
In set<Point2D, p2d_sortby_y>
the second parameter p2d_sortby_y
does not name a type.
struct point_odered_by_y
{
bool operator()(const Point2D& ptd1, const Point2D& ptd2) const
{
/* .. */
}
};
typedef std::set<Point2D, point_odered_by_y> pointset;
pointset s(begin(p2d_set), end(p2d_set));
This would be an easier way to do it:
#include <tuple>
struct SortByYX
{
bool operator ()(const Point2D& lhs, const Point2D& rhs) const
{
return std::tie(lhs.y, lhs.x) < std::tie(rhs.y, rhs.x);
}
};
Then
set<Point2D, SortByYX> p2d_set2(p2d_set.begin(), p2d_set.end());
Edit: std::tie
requires C++11 support, but if you don't have it you can use std::tr1::tie
from <tr1/tuple>
, or boost::tie
if you don't have TR1.
It's usually better to define a functor class to specify the ordering, rather than a function; that way, you can specify it as a template parameter:
struct p2d_sortby_y {
bool operator()(Point2D x, Point2D y) {return whatever;}
};
This has to take its arguments by value or const
reference (not non-const
reference, as yours does) to be used on the constant set members.
You can't directly initialise the new set from a different type of set, but you can initialise it from its range:
set<Point2D,p2d_sortby_y> p2d_set2(p2d_set.begin(), p2d_set.end());