| [ < ] | [ > ] | [ << ] | [ Up ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
5.1.4 Ordering expressions
Sometimes it is necessary to establish a mathematically well-defined ordering
on a set of arbitrary expressions, for example to use expressions as keys
in a std::map<> container, or to bring a vector of expressions into
a canonical order (which is done internally by GiNaC for sums and products).
The operators <, > etc. described in the last section cannot
be used for this, as they don't implement an ordering relation in the
mathematical sense. In particular, they are not guaranteed to be
antisymmetric: if ‘a’ and ‘b’ are different expressions, and
a < b yields false, then b < a doesn't necessarily
yield true.
By default, STL classes and algorithms use the < and ==
operators to compare objects, which are unsuitable for expressions, but GiNaC
provides two functors that can be supplied as proper binary comparison
predicates to the STL:
class ex_is_less : public std::binary_function<ex, ex, bool> {
public:
bool operator()(const ex &lh, const ex &rh) const;
};
class ex_is_equal : public std::binary_function<ex, ex, bool> {
public:
bool operator()(const ex &lh, const ex &rh) const;
};
|
For example, to define a map that maps expressions to strings you
have to use
std::map<ex, std::string, ex_is_less> myMap; |
Omitting the ex_is_less template parameter will introduce spurious
bugs because the map operates improperly.
Other examples for the use of the functors:
std::vector<ex> v;
// fill vector
...
// sort vector
std::sort(v.begin(), v.end(), ex_is_less());
// count the number of expressions equal to '1'
unsigned num_ones = std::count_if(v.begin(), v.end(),
std::bind2nd(ex_is_equal(), 1));
|
The implementation of ex_is_less uses the member function
int ex::compare(const ex & other) const; |
which returns 0 if *this and other are equal, -1
if *this sorts before other, and 1 if *this sorts
after other.
