[ < ] | [ > ] | [ << ] | [ Up ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
6.5.3 Automatic evaluation
When dealing with objects that are just a little more complicated than the
simple string objects we have implemented, chances are that you will want to
have some automatic simplifications or canonicalizations performed on them.
This is done in the evaluation member function eval()
. Let's say that
we wanted all strings automatically converted to lowercase with
non-alphabetic characters stripped, and empty strings removed:
class mystring : public basic { ... public: ex eval(int level = 0) const; ... }; ex mystring::eval(int level) const { string new_str; for (size_t i=0; i<str.length(); i++) { char c = str[i]; if (c >= 'A' && c <= 'Z') new_str += tolower(c); else if (c >= 'a' && c <= 'z') new_str += c; } if (new_str.length() == 0) return 0; else return mystring(new_str).hold(); } |
The level
argument is used to limit the recursion depth of the
evaluation. We don't have any subexpressions in the mystring
class so we are not concerned with this. If we had, we would call the
eval()
functions of the subexpressions with level - 1
as
the argument if level != 1
. The hold()
member function
sets a flag in the object that prevents further evaluation. Otherwise
we might end up in an endless loop. When you want to return the object
unmodified, use return this->hold();
.
Let's confirm that it works:
ex e = mystring("Hello, world!") + mystring("!?#"); cout << e << endl; // -> "helloworld" e = mystring("Wow!") + mystring("WOW") + mystring(" W ** o ** W"); cout << e << endl; // -> 3*"wow" |