kpeter@269: /* -*- mode: C++; indent-tabs-mode: nil; -*-
alpar@267: *
kpeter@269: * 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@268: Several modern languages provide a convenient way to refer the
alpar@268: function parameters by name also when you call the function. It is
alpar@268: especially comfortable in case of a function having tons of parameters
kpeter@269: with natural default values. Sadly, C++ lack this amenity.
alpar@268:
alpar@268: However, with a crafty trick and with some little
alpar@268: inconvenience, it is possible to emulate is.
alpar@268: The example below shows how to do it.
alpar@267:
alpar@267: \code
kpeter@269: class namedFn
alpar@267: {
alpar@267: int _id;
alpar@267: double _val;
alpar@267: int _dim;
kpeter@269:
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() {
kpeter@269: std::cout << "Here comes the function itself\n" <<
kpeter@269: << "With parameters "
kpeter@269: << _id << ", " << _val << ", " << _dim << std::endl;
alpar@267: }
alpar@267: };
alpar@267: \endcode
alpar@267:
alpar@268: Then you can use it like this.
alpar@267:
alpar@267: \code
alpar@267: namedFn().id(3).val(2).run();
alpar@267: \endcode
alpar@267:
alpar@268: The trick is obvious, each "named parameter" changes one component of
alpar@268: the underlying class, then gives back a reference to it. Finally,
alpar@268: run() executes the algorithm itself.
alpar@268:
alpar@267: \note Although it is a class, namedFn is used pretty much like as it were
alpar@268: a function. That it why we called it namedFn instead of \c NamedFn.
alpar@267:
alpar@268: \note In fact, the final .run() could be made unnecessary,
alpar@268: because the algorithm could also be implemented in the destructor of
alpar@268: \c namedFn instead. This however would make it impossible to implement
alpar@268: functions with return values, and would also cause serious problems when
alpar@268: implementing \ref named-templ-func-param "named template parameters".
alpar@268: Therefore, by convention, .run() must be used
alpar@268: explicitly to execute a function having named parameters
alpar@268: everywhere in LEMON.
alpar@267:
alpar@268: \section named-templ-func-param Named Function Template Parameters
alpar@268:
kpeter@269: A named parameter can also be a template function. The usage is
alpar@268: exactly the same, but the implementation behind is a kind of black
alpar@268: magic and they are the dirtiest part of the LEMON code.
alpar@268:
alpar@268: You will probably never need to know how it works, but if you really
alpar@268: committed, have a look at \ref lemon/graph_to_eps.h for an example.
alpar@267:
alpar@267: \section traits-classes Traits Classes
alpar@267:
alpar@268: A similar game can also be played when defining classes. In this case
alpar@268: the type of the class attributes can be changed. Initially we have to
alpar@268: define a special class called Traits Class defining the
alpar@268: default type of the attributes. Then the types of these attributes can
alpar@268: be changed in the same way as described in the next section.
alpar@268:
alpar@268: See \ref lemon::DijkstraDefaultTraits for an
alpar@268: example how a traits class implementation 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@268: the class contains named parameters, we do not have to instantiate again
alpar@268: the class with new traits class, but instead adaptor classes can
alpar@268: be used as shown in the following example.
alpar@267:
alpar@267: \code
kpeter@269: Dijkstra<>::SetPredMap >::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
kpeter@269: 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: */