doc/named-param.dox
 author Alpar Juttner Wed, 29 Jul 2020 14:56:10 +0200 changeset 1433 a278d16bd2d0 parent 463 88ed40ad0d4f permissions -rw-r--r--
Fix clang compilation issue (#634)
 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@463  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@1351  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 run() 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 .run() 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 Therefore, by convention, .run() must be used  alpar@268  74 explicitly to execute a function having named parameters  alpar@268  75 everywhere in LEMON.  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 Traits Class 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 >::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::SetPredMap >::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 */