1[/============================================================================== 2 Copyright (C) 2001-2010 Joel de Guzman 3 Copyright (C) 2001-2005 Dan Marsden 4 Copyright (C) 2001-2010 Thomas Heller 5 6 Distributed under the Boost Software License, Version 1.0. (See accompanying 7 file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) 8===============================================================================/] 9 10[section Lazy Operators] 11 12You can use the usual set of operators to form expressions. Examples: 13 14 arg1 * arg1 15 ref(x) = arg1 + ref(z) 16 arg1 = arg2 + (3 * arg3) 17 ref(x) = arg1[arg2] // assuming arg1 is indexable and arg2 is a valid index 18 19Note the expression: `3 * arg3`. This expression is actually a short-hand 20equivalent to: `val(3) * arg3`. In most cases, like above, you can get away with 21it. But in some cases, you will have to explicitly wrap your values in `val`. 22Rules of thumb: 23 24* In a binary expression (e.g. `3 * arg3`), at least one of the operands must be 25 a phoenix primitive or expression. 26* In a unary expression (e.g. `arg1++`), the single operand must be a phoenix 27 primitive or expression. 28 29If these basic rules are not followed, the result is either an error, or is 30immediately evaluated. Some examples: 31 32 ref(x) = 123 // lazy 33 x = 123 // immediate 34 35 ref(x)[0] // lazy 36 x[0] // immediate 37 38 ref(x)[ref(i)] // lazy 39 ref(x)[i] // lazy (equivalent to ref(x)[val(i)]) 40 x[ref(i)] // illegal (x is not a phoenix primitive or expression) 41 ref(x[ref(i)]) // illegal (x is not a phoenix primitive or expression) 42 43Why are the last two expression illegal? Although `operator[]` looks as 44much like a binary operator as `operator=` above it; the difference is 45that the former must be a member (i.e. `x` must have an `operator[]` 46that takes a phoenix primitive or expression as its argument). This will 47most likely not be the case. 48 49[blurb __tip__ Learn more about operators [link phoenix.modules.operator here.]] 50 51[heading First Practical Example] 52 53We've covered enough ground to present a real world example. We want to find the 54first odd number in an STL container. Normally we use a functor (function 55object) or a function pointer and pass that in to STL's `find_if` generic 56function: 57 58Write a function: 59 60 bool 61 is_odd(int arg1) 62 { 63 return arg1 % 2 == 1; 64 } 65 66Pass a pointer to the function to STL's `find_if` algorithm: 67 68 std::find_if(c.begin(), c.end(), &is_odd) 69 70Using Phoenix, the same can be achieved directly with a one-liner: 71 72 std::find_if(c.begin(), c.end(), arg1 % 2 == 1) 73 74The expression `arg1 % 2 == 1` automagically creates a functor with the expected 75behavior. In FP, this unnamed function is called a lambda function. Unlike the 76function pointer version, which is monomorphic (expects and works only with a 77fixed type int argument), the Phoenix version is fully polymorphic and works 78with any container (of ints, of longs, of bignum, etc.) as long as its elements 79can handle the `arg1 % 2 == 1` expression. 80 81(See [@../../example/find_if.cpp find_if.cpp]) 82 83[blurb __tip__ ...[*That's it, we're done]. Well if you wish to know a little bit 84more, read on...] 85 86[endsect] 87 88