operator.qbk 3.2 KB

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