Обычный способ определения предиката для сортировки - это функтор.
Сделайте так, чтобы ваш класс определил operator()
для сравнения, и вы можете просто передать экземпляр класса в std::sort
.
Так что на самом деле все, что вам нужно сделать, это определить класс следующим образом:
class test
{
vector<expr*> _exprs;
bool operator()(expr* e1, expr* e2);
ExprManager* mg;
}
И тогда вы можете позвонить sort
так:
sort(_exprs->begin(), _exprs->end(), test());
или, конечно, использовать существующий экземпляр класса test
вместо создания нового. Но вы просто передаете экземпляр класса, и вам вообще не нужно упоминать функцию-член.
Если сортировка выполняется в другой функции-члене (она выглядит так, как вы указали в _exprs
), напишите
sort(_exprs->begin(), _exprs->end(), *this);
Следует отметить, что std::sort
, как и большинство других стандартных библиотечных алгоритмов, копирует объект предиката, и поэтому ваш класс предикатов должен иметь возможность безопасно обрабатывать копирование (что ваши классы всегда должны делать в любом случае * 1023) *)
Короче говоря, способ достичь этого - следовать «правилу трех».
Если ваш класс определяет деструктор, конструктор копирования или оператор присваивания, то он почти наверняка определит все три.
Если используется созданный компилятором конструктор копирования, он просто скопирует члены-указатели вашего класса, поэтому у вас будет два объекта, содержащих указатели на один и тот же объект.
Если в классе есть деструктор, который вызывает delete
для этого указателя, то это заканчивается дважды. Что является ошибкой.
Если ваш класс предназначен для копирования (а большая часть стандартной библиотеки требует этого), то вы должны определить соответствующие конструкторы копирования и операторы присваивания для его безопасной реализации (например, скопировать ресурс, на который указывает указатель, или вместо этого используйте умный указатель).
Если ваш класс не предназначен для копирования, то вы должны определить конструктор копирования и операторы присваивания как private
, так что попытки скопировать класс приведут к ошибке во время компиляции вместо сбоев во время выполнения.
Вы должны никогда определять класс, который можно копировать, но он делает это неправильно. Либо определите необходимый конструктор копирования / оператор / деструктор присваивания для обработки копирования, либо сделайте копирование невозможным, сделав копирование ctor / оператора присваивания частным.
Обертывание указателей в динамически распределенную память, принадлежащую классу, в интеллектуальных указателях - это простой способ получить бесплатное копирование.
Если класс содержит только объекты RAII, вам вообще не нужно определять деструктор, и поэтому правило трех не требует, чтобы вы также определяли конструктор копирования и оператор присваивания.