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
|
alpar@1142
|
28 |
with natural default values. Sadly, C++ lacks 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 |
*/
|