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