gravatar
kpeter (Peter Kovacs)
kpeter@inf.elte.hu
Improvements in named-param.dox (ticket #147)
0 1 0
default
1 file changed with 11 insertions and 11 deletions:
↑ Collapse diff ↑
Ignore white space 96 line context
1
/* -*- C++ -*-
1
/* -*- mode: C++; indent-tabs-mode: nil; -*-
2 2
 *
3
 * This file is a part of LEMON, a generic C++ optimization library
3
 * This file is a part of LEMON, a generic C++ optimization library.
4 4
 *
5 5
 * Copyright (C) 2003-2008
6 6
 * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
7 7
 * (Egervary Research Group on Combinatorial Optimization, EGRES).
8 8
 *
9 9
 * Permission to use, modify and distribute this software is granted
10 10
 * provided that this copyright notice appears in all copies. For
11 11
 * precise terms see the accompanying LICENSE file.
12 12
 *
13 13
 * This software is provided "AS IS" with no warranty of any kind,
14 14
 * express or implied, and with no claim as to its suitability for any
15 15
 * purpose.
16 16
 *
17 17
 */
18 18

	
19 19
/*!
20 20

	
21 21
\page named-param Named Parameters
22 22

	
23 23
\section named-func-param Named Function Parameters
24 24

	
25 25
Several modern languages provide a convenient way to refer the
26 26
function parameters by name also when you call the function. It is
27 27
especially comfortable in case of a function having tons of parameters
28
with natural default values. Sadly, C++ lack this amenity. 
28
with natural default values. Sadly, C++ lack this amenity.
29 29

	
30 30
However, with a crafty trick and with some little
31 31
inconvenience, it is possible to emulate is.
32 32
The example below shows how to do it.
33 33

	
34 34
\code
35
class namedFn 
35
class namedFn
36 36
{
37 37
  int _id;
38 38
  double _val;
39 39
  int _dim;
40
  
40

	
41 41
  public:
42 42
  namedFn() : _id(0), _val(1), _dim(2) {}
43 43
  namedFn& id(int p)     { _id  = p ; return *this; }
44 44
  namedFn& val(double p) { _val = p ; return *this; }
45 45
  namedFn& dim(int p)    { _dim = p ; return *this; }
46 46

	
47 47
  run() {
48
  std::cout << "Here comes the function itself\n" <<
49
            << "With parameters "
50
            << _id << ", " << _val << ", " << _dim << std::endl; 
48
    std::cout << "Here comes the function itself\n" <<
49
              << "With parameters "
50
              << _id << ", " << _val << ", " << _dim << std::endl;
51 51
  }
52 52
};
53 53
\endcode
54 54

	
55 55
Then you can use it like this.
56 56

	
57 57
\code
58 58
namedFn().id(3).val(2).run();
59 59
\endcode
60 60

	
61 61
The trick is obvious, each "named parameter" changes one component of
62 62
the underlying class, then gives back a reference to it. Finally,
63 63
<tt>run()</tt> executes the algorithm itself.
64 64

	
65 65
\note Although it is a class, namedFn is used pretty much like as it were
66 66
a function. That it why we called it namedFn instead of \c NamedFn.
67 67

	
68 68
\note In fact, the final <tt>.run()</tt> could be made unnecessary,
69 69
because the algorithm could also be implemented in the destructor of
70 70
\c namedFn instead. This however would make it impossible to implement
71 71
functions with return values, and would also cause serious problems when
72 72
implementing \ref named-templ-func-param "named template parameters".
73 73
<b>Therefore, by convention, <tt>.run()</tt> must be used
74 74
explicitly to execute a function having named parameters
75 75
everywhere in LEMON.</b>
76 76

	
77 77
\section named-templ-func-param Named Function Template Parameters
78 78

	
79
A named parameter can also be a template functions. The usage is
79
A named parameter can also be a template function. The usage is
80 80
exactly the same, but the implementation behind is a kind of black
81 81
magic and they are the dirtiest part of the LEMON code.
82 82

	
83 83
You will probably never need to know how it works, but if you really
84 84
committed, have a look at \ref lemon/graph_to_eps.h for an example.
85 85

	
86 86
\section traits-classes Traits Classes
87 87

	
88 88
A similar game can also be played when defining classes. In this case
89 89
the type of the class attributes can be changed. Initially we have to
90 90
define a special class called <em>Traits Class</em> defining the
91 91
default type of the attributes. Then the types of these attributes can
92 92
be changed in the same way as described in the next section.
93 93

	
94 94
See \ref lemon::DijkstraDefaultTraits for an
95 95
example how a traits class implementation looks like.
96 96

	
97 97
\section named-templ-param Named Class Template Parameters
98 98

	
99 99
If we would like to change the type of an attribute in a class that
100 100
was instantiated by using a traits class as a template parameter, and
101 101
the class contains named parameters, we do not have to instantiate again
102 102
the class with new traits class, but instead adaptor classes can
103 103
be used as shown in the following example.
104 104

	
105 105
\code
106
Dijkstra<>::SetPredNodeMap<NullMap<Node,Node> >::Create
106
Dijkstra<>::SetPredMap<NullMap<Node,Arc> >::Create
107 107
\endcode
108 108

	
109 109
It can also be used in conjunction with other named template
110 110
parameters in arbitrary order.
111 111

	
112 112
\code
113
Dijkstra<>::SetDistMap<MyMap>::SetPredMap<NullMap<Node,Edge> >::Create
113
Dijkstra<>::SetDistMap<MyMap>::SetPredMap<NullMap<Node,Arc> >::Create
114 114
\endcode
115 115

	
116 116
The result will be an instantiated Dijkstra class, in which the
117 117
DistMap and the PredMap is modified.
118 118

	
119 119
*/
0 comments (0 inline)