Improvements in named-param.dox
authorAlpar Juttner <alpar@cs.elte.hu>
Sun, 21 Sep 2008 07:49:57 +0100
changeset 268986d30f5c1c0
parent 267 1eb606fe5591
child 269 f5965bbf1353
Improvements in named-param.dox
doc/named-param.dox
     1.1 --- a/doc/named-param.dox	Sun Sep 21 06:13:05 2008 +0100
     1.2 +++ b/doc/named-param.dox	Sun Sep 21 07:49:57 2008 +0100
     1.3 @@ -22,21 +22,14 @@
     1.4  
     1.5  \section named-func-param Named Function Parameters
     1.6  
     1.7 -C++ makes it possible to use default parameter values when calling a
     1.8 -function. In such a case we do not have to give value for parameters,
     1.9 -the program will use the default ones.  Unfortunately sometimes this
    1.10 -is not enough. If we do not want to give values for all the
    1.11 -parameters, only for some of them we come across problems, because an
    1.12 -arbitrary set of parameters cannot be omitted. On the other hand
    1.13 -parameters have a fixed order in the head of the function.  C++ can
    1.14 -apply the default values only in the back of the order, if we do not
    1.15 -give other value for them.  So we can not give the function for
    1.16 -example the value of the first, and the third parameter, expecting
    1.17 -that the program will aplly the default value for the second
    1.18 -parameter.  However sometimes we would like to use some functinos
    1.19 -exactly in this way. With a crafty trick and with some little
    1.20 -inconvenience this is possible. We have implemented this little trick
    1.21 -as an example below.
    1.22 +Several modern languages provide a convenient way to refer the
    1.23 +function parameters by name also when you call the function. It is
    1.24 +especially comfortable in case of a function having tons of parameters
    1.25 +with natural default values. Sadly, C++ lack this amenity. 
    1.26 +
    1.27 +However, with a crafty trick and with some little
    1.28 +inconvenience, it is possible to emulate is.
    1.29 +The example below shows how to do it.
    1.30  
    1.31  \code
    1.32  class namedFn 
    1.33 @@ -52,63 +45,62 @@
    1.34    namedFn& dim(int p)    { _dim = p ; return *this; }
    1.35  
    1.36    run() {
    1.37 -    printf("Here is the function itself.");
    1.38 +  std::cout << "Here comes the function itself\n" <<
    1.39 +            << "With parameters "
    1.40 +            << _id << ", " << _val << ", " << _dim << std::endl; 
    1.41    }
    1.42  };
    1.43  \endcode
    1.44  
    1.45 +Then you can use it like this.
    1.46  
    1.47 -The usage is the following.
    1.48 -
    1.49 -We have to define a class, let's call it \c namedFn.  Let us assume that
    1.50 -we would like to use a parameter, called \c X. In the \c namedFn class we
    1.51 -have to define an \c _X attribute, and a function \c X. The function
    1.52 -expects a parameter with the type of \c _X, and sets the value of
    1.53 -\c _X. After setting the value the function returns the class itself. The
    1.54 -class also have to have a function, called for example <tt>run()</tt>, we have
    1.55 -to implement here the original function itself. The constructor of the
    1.56 -class have to give all the attributes like \c _X the default values of
    1.57 -them.
    1.58 -
    1.59 -If we instantiate this class, the default values will be set for the
    1.60 -attributes (originally the parameters), initially. If we call function
    1.61 -\c X, we get a class with the modified parameter value of
    1.62 -\c X. Therefore we can modify any parameter-value, independently from the
    1.63 -order. To run the algorithm we have to call the <tt>run()</tt> function at the
    1.64 -end of the row.
    1.65 -
    1.66 -Example:
    1.67  \code
    1.68  namedFn().id(3).val(2).run();
    1.69  \endcode
    1.70  
    1.71 +The trick is obvious, each "named parameter" changes one component of
    1.72 +the underlying class, then gives back a reference to it. Finally,
    1.73 +<tt>run()</tt> executes the algorithm itself.
    1.74 +
    1.75  \note Although it is a class, namedFn is used pretty much like as it were
    1.76 -a function. That it why it is called namedFn and not \c NamedFn.
    1.77 +a function. That it why we called it namedFn instead of \c NamedFn.
    1.78  
    1.79 -\note In fact, the final <tt>.run()</tt> could be made unnecessary if the
    1.80 -actual function code were put in the destructor instead. This however would make
    1.81 -hard to implement functions with return values, and would also make the
    1.82 -implementation of \ref named-templ-func-param "named template parameters"
    1.83 -very problematic. <b>Therefore, by convention, <tt>.run()</tt> must be used
    1.84 -to explicitly execute function having named parameters in Lemon.</b>
    1.85 +\note In fact, the final <tt>.run()</tt> could be made unnecessary,
    1.86 +because the algorithm could also be implemented in the destructor of
    1.87 +\c namedFn instead. This however would make it impossible to implement
    1.88 +functions with return values, and would also cause serious problems when
    1.89 +implementing \ref named-templ-func-param "named template parameters".
    1.90 +<b>Therefore, by convention, <tt>.run()</tt> must be used
    1.91 +explicitly to execute a function having named parameters
    1.92 +everywhere in LEMON.</b>
    1.93  
    1.94 +\section named-templ-func-param Named Function Template Parameters
    1.95 +
    1.96 +A named parameter can also be a template functions. The usage is
    1.97 +exactly the same, but the implementation behind is a kind of black
    1.98 +magic and they are the dirtiest part of the LEMON code.
    1.99 +
   1.100 +You will probably never need to know how it works, but if you really
   1.101 +committed, have a look at \ref lemon/graph_to_eps.h for an example.
   1.102  
   1.103  \section traits-classes Traits Classes
   1.104  
   1.105 -The procedure above can also be applied when defining classes. In this
   1.106 -case the type of the attributes can be changed.  Initially we have to
   1.107 -define a class with the default attribute types. This is the so called
   1.108 -Traits Class. Later on the types of these attributes can be changed,
   1.109 -as described below. In our software \ref lemon::DijkstraDefaultTraits is an
   1.110 -example of how a traits class looks like.
   1.111 +A similar game can also be played when defining classes. In this case
   1.112 +the type of the class attributes can be changed. Initially we have to
   1.113 +define a special class called <em>Traits Class</em> defining the
   1.114 +default type of the attributes. Then the types of these attributes can
   1.115 +be changed in the same way as described in the next section.
   1.116 +
   1.117 +See \ref lemon::DijkstraDefaultTraits for an
   1.118 +example how a traits class implementation looks like.
   1.119  
   1.120  \section named-templ-param Named Class Template Parameters
   1.121  
   1.122  If we would like to change the type of an attribute in a class that
   1.123  was instantiated by using a traits class as a template parameter, and
   1.124 -the class contains named parameters, we do not have to reinstantiate
   1.125 -the class with new traits class. Instead of that, adaptor classes can
   1.126 -be used like in the following cases.
   1.127 +the class contains named parameters, we do not have to instantiate again
   1.128 +the class with new traits class, but instead adaptor classes can
   1.129 +be used as shown in the following example.
   1.130  
   1.131  \code
   1.132  Dijkstra<>::SetPredNodeMap<NullMap<Node,Node> >::Create
   1.133 @@ -124,10 +116,4 @@
   1.134  The result will be an instantiated Dijkstra class, in which the
   1.135  DistMap and the PredMap is modified.
   1.136  
   1.137 -\section named-templ-func-param Named Function Template Parameters
   1.138 -
   1.139 -If the class has so called wizard functions, the new class with the
   1.140 -modified tpye of attributes can be returned by the appropriate wizard
   1.141 -function. The usage of these wizard functions is the following:
   1.142 -
   1.143  */