hello_world.qbk 3.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384
  1. [/
  2. / Copyright (c) 2008 Eric Niebler
  3. /
  4. / Distributed under the Boost Software License, Version 1.0. (See accompanying
  5. / file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
  6. /]
  7. [/==================]
  8. [section Hello World]
  9. [/==================]
  10. Below is a very simple program that uses Proto to build an expression template
  11. and then execute it.
  12. #include <iostream>
  13. #include <boost/proto/proto.hpp>
  14. #include <boost/typeof/std/ostream.hpp>
  15. using namespace boost;
  16. proto::terminal< std::ostream & >::type cout_ = { std::cout };
  17. template< typename Expr >
  18. void evaluate( Expr const & expr )
  19. {
  20. proto::default_context ctx;
  21. proto::eval(expr, ctx);
  22. }
  23. int main()
  24. {
  25. evaluate( cout_ << "hello" << ',' << " world" );
  26. return 0;
  27. }
  28. This program outputs the following:
  29. [pre
  30. hello, world
  31. ]
  32. This program builds an object representing the output operation and passes
  33. it to an `evaluate()` function, which then executes it.
  34. The basic idea of expression templates is to overload all the operators so
  35. that, rather than evaluating the expression immediately, they build a tree-like
  36. representation of the expression so that it can be evaluated later. For each
  37. operator in an expression, at least one operand must be Protofied in order
  38. for Proto's operator overloads to be found. In the expression ...
  39. cout_ << "hello" << ',' << " world"
  40. ... the Protofied sub-expression is `cout_`, which is the Proto-ification of
  41. `std::cout`. The presence of `cout_` "infects" the expression, and brings
  42. Proto's tree-building operator overloads into consideration. Any literals in
  43. the expression are then Protofied by wrapping them in a Proto terminal before
  44. they are combined into larger Proto expressions.
  45. Once Proto's operator overloads have built the expression tree, the expression
  46. can be lazily evaluated later by walking the tree. That is what `proto::eval()`
  47. does. It is a general tree-walking expression evaluator, whose behavior is
  48. customizable via a /context/ parameter. The use of _default_context_ assigns
  49. the standard meanings to the operators in the expression. (By using a different
  50. context, you could give the operators in your expressions different semantics.
  51. By default, Proto makes no assumptions about what operators actually /mean/.)
  52. [/==============================]
  53. [heading Proto Design Philosophy]
  54. [/==============================]
  55. Before we continue, let's use the above example to illustrate an important
  56. design principle of Proto's. The expression template created in the ['hello
  57. world] example is totally general and abstract. It is not tied in any way to
  58. any particular domain or application, nor does it have any particular meaning
  59. or behavior on its own, until it is evaluated in a /context/. Expression
  60. templates are really just heterogeneous trees, which might mean something in
  61. one domain, and something else entirely in a different one.
  62. As we'll see later, there is a way to create Proto expression trees that are
  63. ['not] purely abstract, and that have meaning and behaviors independent of any
  64. context. There is also a way to control which operators are overloaded for your
  65. particular domain. But that is not the default behavior. We'll see later why
  66. the default is often a good thing.
  67. [endsect]