doc/named-param.dox
author Peter Kovacs <kpeter@inf.elte.hu>
Thu, 11 Feb 2010 07:39:57 +0100
changeset 827 8131c2b9f59a
parent 269 f5965bbf1353
permissions -rw-r--r--
Port planar image from SVN -r3524 (#62)
     1 /* -*- mode: C++; indent-tabs-mode: nil; -*-
     2  *
     3  * This file is a part of LEMON, a generic C++ optimization library.
     4  *
     5  * Copyright (C) 2003-2009
     6  * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
     7  * (Egervary Research Group on Combinatorial Optimization, EGRES).
     8  *
     9  * Permission to use, modify and distribute this software is granted
    10  * provided that this copyright notice appears in all copies. For
    11  * precise terms see the accompanying LICENSE file.
    12  *
    13  * This software is provided "AS IS" with no warranty of any kind,
    14  * express or implied, and with no claim as to its suitability for any
    15  * purpose.
    16  *
    17  */
    18 
    19 /*!
    20 
    21 \page named-param Named Parameters
    22 
    23 \section named-func-param Named Function Parameters
    24 
    25 Several modern languages provide a convenient way to refer the
    26 function parameters by name also when you call the function. It is
    27 especially comfortable in case of a function having tons of parameters
    28 with natural default values. Sadly, C++ lack this amenity.
    29 
    30 However, with a crafty trick and with some little
    31 inconvenience, it is possible to emulate is.
    32 The example below shows how to do it.
    33 
    34 \code
    35 class namedFn
    36 {
    37   int _id;
    38   double _val;
    39   int _dim;
    40 
    41   public:
    42   namedFn() : _id(0), _val(1), _dim(2) {}
    43   namedFn& id(int p)     { _id  = p ; return *this; }
    44   namedFn& val(double p) { _val = p ; return *this; }
    45   namedFn& dim(int p)    { _dim = p ; return *this; }
    46 
    47   run() {
    48     std::cout << "Here comes the function itself\n" <<
    49               << "With parameters "
    50               << _id << ", " << _val << ", " << _dim << std::endl;
    51   }
    52 };
    53 \endcode
    54 
    55 Then you can use it like this.
    56 
    57 \code
    58 namedFn().id(3).val(2).run();
    59 \endcode
    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 
    65 \note Although it is a class, namedFn is used pretty much like as it were
    66 a function. That it why we called it namedFn instead of \c NamedFn.
    67 
    68 \note In fact, the final <tt>.run()</tt> could be made unnecessary,
    69 because the algorithm could also be implemented in the destructor of
    70 \c namedFn instead. This however would make it impossible to implement
    71 functions with return values, and would also cause serious problems when
    72 implementing \ref named-templ-func-param "named template parameters".
    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>
    76 
    77 \section named-templ-func-param Named Function Template Parameters
    78 
    79 A named parameter can also be a template function. 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.
    85 
    86 \section traits-classes Traits Classes
    87 
    88 A similar game can also be played when defining classes. In this case
    89 the type of the class attributes can be changed. Initially we have to
    90 define a special class called <em>Traits Class</em> defining the
    91 default type of the attributes. Then the types of these attributes can
    92 be changed in the same way as described in the next section.
    93 
    94 See \ref lemon::DijkstraDefaultTraits for an
    95 example how a traits class implementation looks like.
    96 
    97 \section named-templ-param Named Class Template Parameters
    98 
    99 If we would like to change the type of an attribute in a class that
   100 was instantiated by using a traits class as a template parameter, and
   101 the class contains named parameters, we do not have to instantiate again
   102 the class with new traits class, but instead adaptor classes can
   103 be used as shown in the following example.
   104 
   105 \code
   106 Dijkstra<>::SetPredMap<NullMap<Node,Arc> >::Create
   107 \endcode
   108 
   109 It can also be used in conjunction with other named template
   110 parameters in arbitrary order.
   111 
   112 \code
   113 Dijkstra<>::SetDistMap<MyMap>::SetPredMap<NullMap<Node,Arc> >::Create
   114 \endcode
   115 
   116 The result will be an instantiated Dijkstra class, in which the
   117 DistMap and the PredMap is modified.
   118 
   119 */