19 июля 2009

Sorting by several fields

Как вы сортируете по нескольким критериям?
struct foo
{
A a; B b; C c; D d;
X x; Y y;
};

// нужно отсортировать по a, затем по b, затем по c, ну а затем еще и по d
// по x и y сортировать не нужно
bool s(foo const &l, foo const &r)
{
if (l.a < r.a) return true;
if (l.a > r.a) return false;
if (l.b < r.b) return true;
if (l.b > r.b) return false;
if (l.c < r.c) return true;
if (l.c > r.c) return false;
return l.d < r.d;
}

std::vector<foo> f;
std::sort(f.begin(), f.end(), s);

Признаюсь, я примерно так раньше и сортировал. Хотя по сути-то [a,b,c,d] - это ж по-сути обычный кортеж, а для них уже есть готовые библиотеки. И операции сравнения кортежей там должны быть, в этих библиотеках. Нужно просто загнать l и r в кортежи (только для скорости - не в [A,B,C,D], а в [const&A,const&B,const&C,const&D]), и сравнить:
#include <boost/tuple/tuple_comparison.hpp>

bool s(foo const &l, foo const &r)
{
return boost::tie(l.a, l.b, l.c, l.d) < boost::tie(r.a, r.b, r.c, r.d);
}

16 июля 2009

Static member definition

Интересно, что статический член класса нельзя определить прямо в декларации класса:
class foo
{
static std::string s('hello world');
};
А иногда сильно этого хочется - например в декларации шаблона. Или просто в каком-нибудь header-only классе. Самое интересное, что внутри функции такое провернуть можно. Поэтому можно сделать финт ушами - сделать доступ к статическому члену через member-функцию:
class foo
{
static std::string &s()
{
static std::string impl('hello world');
return impl;
}
};
Синтаксис при обращении немного поменяется - s() вместо s, но часто оно того стоит.