doc/named-param.dox
changeset 268 986d30f5c1c0
parent 267 1eb606fe5591
child 269 f5965bbf1353
equal deleted inserted replaced
0:9747e382dffb 1:0ff881002c44
    20 
    20 
    21 \page named-param Named Parameters
    21 \page named-param Named Parameters
    22 
    22 
    23 \section named-func-param Named Function Parameters
    23 \section named-func-param Named Function Parameters
    24 
    24 
    25 C++ makes it possible to use default parameter values when calling a
    25 Several modern languages provide a convenient way to refer the
    26 function. In such a case we do not have to give value for parameters,
    26 function parameters by name also when you call the function. It is
    27 the program will use the default ones.  Unfortunately sometimes this
    27 especially comfortable in case of a function having tons of parameters
    28 is not enough. If we do not want to give values for all the
    28 with natural default values. Sadly, C++ lack this amenity. 
    29 parameters, only for some of them we come across problems, because an
    29 
    30 arbitrary set of parameters cannot be omitted. On the other hand
    30 However, with a crafty trick and with some little
    31 parameters have a fixed order in the head of the function.  C++ can
    31 inconvenience, it is possible to emulate is.
    32 apply the default values only in the back of the order, if we do not
    32 The example below shows how to do it.
    33 give other value for them.  So we can not give the function for
       
    34 example the value of the first, and the third parameter, expecting
       
    35 that the program will aplly the default value for the second
       
    36 parameter.  However sometimes we would like to use some functinos
       
    37 exactly in this way. With a crafty trick and with some little
       
    38 inconvenience this is possible. We have implemented this little trick
       
    39 as an example below.
       
    40 
    33 
    41 \code
    34 \code
    42 class namedFn 
    35 class namedFn 
    43 {
    36 {
    44   int _id;
    37   int _id;
    50   namedFn& id(int p)     { _id  = p ; return *this; }
    43   namedFn& id(int p)     { _id  = p ; return *this; }
    51   namedFn& val(double p) { _val = p ; return *this; }
    44   namedFn& val(double p) { _val = p ; return *this; }
    52   namedFn& dim(int p)    { _dim = p ; return *this; }
    45   namedFn& dim(int p)    { _dim = p ; return *this; }
    53 
    46 
    54   run() {
    47   run() {
    55     printf("Here is the function itself.");
    48   std::cout << "Here comes the function itself\n" <<
       
    49             << "With parameters "
       
    50             << _id << ", " << _val << ", " << _dim << std::endl; 
    56   }
    51   }
    57 };
    52 };
    58 \endcode
    53 \endcode
    59 
    54 
       
    55 Then you can use it like this.
    60 
    56 
    61 The usage is the following.
       
    62 
       
    63 We have to define a class, let's call it \c namedFn.  Let us assume that
       
    64 we would like to use a parameter, called \c X. In the \c namedFn class we
       
    65 have to define an \c _X attribute, and a function \c X. The function
       
    66 expects a parameter with the type of \c _X, and sets the value of
       
    67 \c _X. After setting the value the function returns the class itself. The
       
    68 class also have to have a function, called for example <tt>run()</tt>, we have
       
    69 to implement here the original function itself. The constructor of the
       
    70 class have to give all the attributes like \c _X the default values of
       
    71 them.
       
    72 
       
    73 If we instantiate this class, the default values will be set for the
       
    74 attributes (originally the parameters), initially. If we call function
       
    75 \c X, we get a class with the modified parameter value of
       
    76 \c X. Therefore we can modify any parameter-value, independently from the
       
    77 order. To run the algorithm we have to call the <tt>run()</tt> function at the
       
    78 end of the row.
       
    79 
       
    80 Example:
       
    81 \code
    57 \code
    82 namedFn().id(3).val(2).run();
    58 namedFn().id(3).val(2).run();
    83 \endcode
    59 \endcode
    84 
    60 
       
    61 The trick is obvious, each "named parameter" changes one component of
       
    62 the underlying class, then gives back a reference to it. Finally,
       
    63 <tt>run()</tt> executes the algorithm itself.
       
    64 
    85 \note Although it is a class, namedFn is used pretty much like as it were
    65 \note Although it is a class, namedFn is used pretty much like as it were
    86 a function. That it why it is called namedFn and not \c NamedFn.
    66 a function. That it why we called it namedFn instead of \c NamedFn.
    87 
    67 
    88 \note In fact, the final <tt>.run()</tt> could be made unnecessary if the
    68 \note In fact, the final <tt>.run()</tt> could be made unnecessary,
    89 actual function code were put in the destructor instead. This however would make
    69 because the algorithm could also be implemented in the destructor of
    90 hard to implement functions with return values, and would also make the
    70 \c namedFn instead. This however would make it impossible to implement
    91 implementation of \ref named-templ-func-param "named template parameters"
    71 functions with return values, and would also cause serious problems when
    92 very problematic. <b>Therefore, by convention, <tt>.run()</tt> must be used
    72 implementing \ref named-templ-func-param "named template parameters".
    93 to explicitly execute function having named parameters in Lemon.</b>
    73 <b>Therefore, by convention, <tt>.run()</tt> must be used
       
    74 explicitly to execute a function having named parameters
       
    75 everywhere in LEMON.</b>
    94 
    76 
       
    77 \section named-templ-func-param Named Function Template Parameters
       
    78 
       
    79 A named parameter can also be a template functions. The usage is
       
    80 exactly the same, but the implementation behind is a kind of black
       
    81 magic and they are the dirtiest part of the LEMON code.
       
    82 
       
    83 You will probably never need to know how it works, but if you really
       
    84 committed, have a look at \ref lemon/graph_to_eps.h for an example.
    95 
    85 
    96 \section traits-classes Traits Classes
    86 \section traits-classes Traits Classes
    97 
    87 
    98 The procedure above can also be applied when defining classes. In this
    88 A similar game can also be played when defining classes. In this case
    99 case the type of the attributes can be changed.  Initially we have to
    89 the type of the class attributes can be changed. Initially we have to
   100 define a class with the default attribute types. This is the so called
    90 define a special class called <em>Traits Class</em> defining the
   101 Traits Class. Later on the types of these attributes can be changed,
    91 default type of the attributes. Then the types of these attributes can
   102 as described below. In our software \ref lemon::DijkstraDefaultTraits is an
    92 be changed in the same way as described in the next section.
   103 example of how a traits class looks like.
    93 
       
    94 See \ref lemon::DijkstraDefaultTraits for an
       
    95 example how a traits class implementation looks like.
   104 
    96 
   105 \section named-templ-param Named Class Template Parameters
    97 \section named-templ-param Named Class Template Parameters
   106 
    98 
   107 If we would like to change the type of an attribute in a class that
    99 If we would like to change the type of an attribute in a class that
   108 was instantiated by using a traits class as a template parameter, and
   100 was instantiated by using a traits class as a template parameter, and
   109 the class contains named parameters, we do not have to reinstantiate
   101 the class contains named parameters, we do not have to instantiate again
   110 the class with new traits class. Instead of that, adaptor classes can
   102 the class with new traits class, but instead adaptor classes can
   111 be used like in the following cases.
   103 be used as shown in the following example.
   112 
   104 
   113 \code
   105 \code
   114 Dijkstra<>::SetPredNodeMap<NullMap<Node,Node> >::Create
   106 Dijkstra<>::SetPredNodeMap<NullMap<Node,Node> >::Create
   115 \endcode
   107 \endcode
   116 
   108 
   122 \endcode
   114 \endcode
   123 
   115 
   124 The result will be an instantiated Dijkstra class, in which the
   116 The result will be an instantiated Dijkstra class, in which the
   125 DistMap and the PredMap is modified.
   117 DistMap and the PredMap is modified.
   126 
   118 
   127 \section named-templ-func-param Named Function Template Parameters
       
   128 
       
   129 If the class has so called wizard functions, the new class with the
       
   130 modified tpye of attributes can be returned by the appropriate wizard
       
   131 function. The usage of these wizard functions is the following:
       
   132 
       
   133 */
   119 */