У меня есть два решения, оба из которых были протестированы:
Во-первых, общий код для обоих:
class Point2D {
public:
Point2D(int x, int y) : x_(x), y_(y) { }
int getX() const { return x_; }
int getY() const { return y_; }
private:
int x_, y_;
};
И основная функция ...
int main(int argc, char *argv[])
{
Points s1(compareByX);
Points s2(compareByY);
const int size = 1750;
for (int x = -size; x <= size; ++x) {
for (int y = -size; y <= size; ++y) {
Point2D p(x, y);
s1.insert(p);
s2.insert(p);
}
}
return 0;
}
Теперь для решения 1:
#include <tr1/functional>
#include <set>
typedef ::std::tr1::function<bool (const Point2D &, const Point2D &)> comparefunc_t;
typedef ::std::set <Point2D, comparefunc_t> Points;
bool compareByX(const Point2D &a, const Point2D &b)
{
return (a.getX() != b.getX()) ?
(a.getX() < b.getX()) : (a.getY() < b.getY());
}
bool compareByY(const Point2D &a, const Point2D &b)
{
return (a.getY() != b.getY()) ?
(a.getY() < b.getY()) : (a.getX() < b.getX());
}
И гораздо более длинное решение 2:
class Point2DComparator {
public:
virtual bool operator()(const Point2D &a, const Point2D &b) const = 0;
protected:
const Point2DComparator &operator =(const Point2DComparator &b) {
return *this;
}
Point2DComparator(const Point2DComparator &b) { }
Point2DComparator() { }
};
class Point2DComparatorEnvelope : public Point2DComparator {
public:
Point2DComparatorEnvelope(const Point2DComparator &letter)
: letter_(letter)
{
}
virtual bool operator()(const Point2D &a, const Point2D &b) const {
return letter_(a, b);
}
private:
const Point2DComparator &letter_;
};
class XComparator : public Point2DComparator {
public:
virtual bool operator() ( const Point2D &a, const Point2D &b) const {
return (a.getX() != b.getX()) ?
(a.getX() < b.getX()) : (a.getY() < b.getY());
}
};
class YComparator : public Point2DComparator {
public:
virtual bool operator() ( const Point2D &a, const Point2D &b) const {
return (a.getY() != b.getY()) ?
(a.getY() < b.getY()) : (a.getX() < b.getX());
}
};
typedef ::std::set<Point2D, Point2DComparatorEnvelope> Points;
XComparator compareByX;
YComparator compareByY;
Они кажутся виртуальными (не каламбур) идентичны по производительности.Второе намного сложнее, хотя, если вы посмотрите на внутреннюю часть ::std::tr1::function
, вы увидите, что она очень волосатая.Второй в основном полезен для демонстрационных целей.ИМХО, стандарт нарушен за требование взломать конверт / письмо, чтобы все это работало.