alpar@267: /* -*- C++ -*- alpar@267: * alpar@267: * This file is a part of LEMON, a generic C++ optimization library alpar@267: * alpar@267: * Copyright (C) 2003-2008 alpar@267: * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport alpar@267: * (Egervary Research Group on Combinatorial Optimization, EGRES). alpar@267: * alpar@267: * Permission to use, modify and distribute this software is granted alpar@267: * provided that this copyright notice appears in all copies. For alpar@267: * precise terms see the accompanying LICENSE file. alpar@267: * alpar@267: * This software is provided "AS IS" with no warranty of any kind, alpar@267: * express or implied, and with no claim as to its suitability for any alpar@267: * purpose. alpar@267: * alpar@267: */ alpar@267: alpar@267: /*! alpar@267: alpar@267: \page named-param Named Parameters alpar@267: alpar@267: \section named-func-param Named Function Parameters alpar@267: alpar@267: C++ makes it possible to use default parameter values when calling a alpar@267: function. In such a case we do not have to give value for parameters, alpar@267: the program will use the default ones. Unfortunately sometimes this alpar@267: is not enough. If we do not want to give values for all the alpar@267: parameters, only for some of them we come across problems, because an alpar@267: arbitrary set of parameters cannot be omitted. On the other hand alpar@267: parameters have a fixed order in the head of the function. C++ can alpar@267: apply the default values only in the back of the order, if we do not alpar@267: give other value for them. So we can not give the function for alpar@267: example the value of the first, and the third parameter, expecting alpar@267: that the program will aplly the default value for the second alpar@267: parameter. However sometimes we would like to use some functinos alpar@267: exactly in this way. With a crafty trick and with some little alpar@267: inconvenience this is possible. We have implemented this little trick alpar@267: as an example below. alpar@267: alpar@267: \code alpar@267: class namedFn alpar@267: { alpar@267: int _id; alpar@267: double _val; alpar@267: int _dim; alpar@267: alpar@267: public: alpar@267: namedFn() : _id(0), _val(1), _dim(2) {} alpar@267: namedFn& id(int p) { _id = p ; return *this; } alpar@267: namedFn& val(double p) { _val = p ; return *this; } alpar@267: namedFn& dim(int p) { _dim = p ; return *this; } alpar@267: alpar@267: run() { alpar@267: printf("Here is the function itself."); alpar@267: } alpar@267: }; alpar@267: \endcode alpar@267: alpar@267: alpar@267: The usage is the following. alpar@267: alpar@267: We have to define a class, let's call it \c namedFn. Let us assume that alpar@267: we would like to use a parameter, called \c X. In the \c namedFn class we alpar@267: have to define an \c _X attribute, and a function \c X. The function alpar@267: expects a parameter with the type of \c _X, and sets the value of alpar@267: \c _X. After setting the value the function returns the class itself. The alpar@267: class also have to have a function, called for example run(), we have alpar@267: to implement here the original function itself. The constructor of the alpar@267: class have to give all the attributes like \c _X the default values of alpar@267: them. alpar@267: alpar@267: If we instantiate this class, the default values will be set for the alpar@267: attributes (originally the parameters), initially. If we call function alpar@267: \c X, we get a class with the modified parameter value of alpar@267: \c X. Therefore we can modify any parameter-value, independently from the alpar@267: order. To run the algorithm we have to call the run() function at the alpar@267: end of the row. alpar@267: alpar@267: Example: alpar@267: \code alpar@267: namedFn().id(3).val(2).run(); alpar@267: \endcode alpar@267: alpar@267: \note Although it is a class, namedFn is used pretty much like as it were alpar@267: a function. That it why it is called namedFn and not \c NamedFn. alpar@267: alpar@267: \note In fact, the final .run() could be made unnecessary if the alpar@267: actual function code were put in the destructor instead. This however would make alpar@267: hard to implement functions with return values, and would also make the alpar@267: implementation of \ref named-templ-func-param "named template parameters" alpar@267: very problematic. Therefore, by convention, .run() must be used alpar@267: to explicitly execute function having named parameters in Lemon. alpar@267: alpar@267: alpar@267: \section traits-classes Traits Classes alpar@267: alpar@267: The procedure above can also be applied when defining classes. In this alpar@267: case the type of the attributes can be changed. Initially we have to alpar@267: define a class with the default attribute types. This is the so called alpar@267: Traits Class. Later on the types of these attributes can be changed, alpar@267: as described below. In our software \ref lemon::DijkstraDefaultTraits is an alpar@267: example of how a traits class looks like. alpar@267: alpar@267: \section named-templ-param Named Class Template Parameters alpar@267: alpar@267: If we would like to change the type of an attribute in a class that alpar@267: was instantiated by using a traits class as a template parameter, and alpar@267: the class contains named parameters, we do not have to reinstantiate alpar@267: the class with new traits class. Instead of that, adaptor classes can alpar@267: be used like in the following cases. alpar@267: alpar@267: \code alpar@267: Dijkstra<>::SetPredNodeMap >::Create alpar@267: \endcode alpar@267: alpar@267: It can also be used in conjunction with other named template alpar@267: parameters in arbitrary order. alpar@267: alpar@267: \code alpar@267: Dijkstra<>::SetDistMap::SetPredMap >::Create alpar@267: \endcode alpar@267: alpar@267: The result will be an instantiated Dijkstra class, in which the alpar@267: DistMap and the PredMap is modified. alpar@267: alpar@267: \section named-templ-func-param Named Function Template Parameters alpar@267: alpar@267: If the class has so called wizard functions, the new class with the alpar@267: modified tpye of attributes can be returned by the appropriate wizard alpar@267: function. The usage of these wizard functions is the following: alpar@267: alpar@267: */