This facility provides a mechanism for lazily evaluating operators. Syntactically, a lazy operator looks and feels like an ordinary C/C++ infix, prefix or postfix operator. The operator application looks the same. However, unlike ordinary operators, the actual operator execution is deferred. Samples:
arg1 + arg2 1 + arg1 * arg2 1 / -arg1 arg1 < 150
We have seen the lazy operators in action (see sample2.cpp) above. Let's go back and examine it a little bit further:
find_if(c.begin(), c.end(), arg1 % 2 == 1)
Through operator overloading, the expression "arg1 % 2 == 1" actually generates a composite. This composite object is passed on to STL's find_if function. In the viewpoint of STL, the composite is simply a functor expecting a single argument, the container's element. For each element in the container 'c', the element is passed on as an argument (arg1) to the composite (functor). The composite (functor) checks if this is an odd value based on the expression "arg1 % 2 == 1" where arg1 is iteratively replaced by the container's element.
A set of classes implement all the C++ free operators. Like lazy functions (see functions), lazy operators are not immediately executed when invoked. Instead, a composite (see composite) object is created and returned to the caller. Example:
(arg1 + arg2) * arg3
does nothing more than return a composite. A second function call will evaluate the actual operators. Example:
int i = 4, j = 5, k = 6; cout << ((arg1 + arg2) * arg3)(i, j, k);
will print out "54".
Arbitrarily complex expressions can be lazily evaluated following three simple rules:
-(arg1 + 3 + 6)
Lazy-operator application is highly contagious. In most cases, a single argN actor infects all its immediate neighbors within a group (first level or parenthesized expression).
Take note that although at least one of the operands must be a valid actor class in order for lazy evaluation to take effect, if this is not the case and we still want to lazily evaluate an expression, we can use var(x), val(x) or const_ref(x) to transform the operand into a valid action object (see primitives). Example:
val(1) << 3;
prefix: ~, !, -, +, ++, --, & (reference), * (dereference) postfix: ++, --
=, , +=, -=, *=, /=, %=, &=, |=, ^=, <<=, >>= +, -, *, /, %, &, |, ^, <<, >> ==, !=, <, >, <=, >= &&, ||
Copyright © 2001-2002 Joel de Guzman
Permission to copy, use, modify, sell and distribute this document is granted provided this copyright notice appears in all copies. This document is provided "as is" without express or implied warranty, and with no claim as to its suitability for any purpose.