From: Stjepan Rajko (stipe_at_[hidden])
Date: 2008-01-10 22:54:06
On Jan 10, 2008 7:58 PM, Joel de Guzman <joel_at_[hidden]> wrote:
> Tobias Schwinger wrote:
> > Joel de Guzman wrote:
> >> Single function:
> >> I'm a strong advocate of smaller is better. Modularity matters.
> >> Big classes (or in this case function objects), metaprogram blobs
> >> (i.e. traits), humongous enums, and all such sort of dinosours :-)
> >> are best avoided. They are convenient up to a certain extent and
> >> becomes unmanageable beyond a certain limit.
> >> In all of my use cases, I have N functions that are provided
> >> elsewhere and I have no control over (e.g. parser functions).
> >> I insist that this is the more common use case. Grouping
> >> them into a single big struct is an unnecessary and cumbersome
> >> step.
> >> Still, if people insist, I outlined a way to convert the big
> >> function object to smaller 'bound' objects, in another post.
> >> Just bind 'em into smaller function chunks.
> > I think it's a misconception to assume that a single function object
> > will be inherently big.
> It's not about "big". It's about modular vs. monolithic. The
> best designs, IMO, are modular.
> > It's just another degree of freedom (namely what to look up) exposed to
> > the user. Whether one can appreciate it seems a matter of taste to me...
> >>> A ---> B: function := L(I): functions[I]()
> >>> B ---> A: transform(cases, L(I): make_pair<I>(bind(function,I())))
> > ...and I happen to prefer the first transform.
> I guess that reasoning is due to your thinking that the one
> monolithic automation functor is more common. That's where I
> disagree, vehemently(!). I've got lots of use cases that show
> otherwise. I assert that the more common case is to have as
> input N functions (member/free function pointers, binded
> functions, boost.functions, etc) and the switch_ is used to
> Let me emphasize this to the strongest extent: A single monolithic
> function for the cases in a switch facility is simply and utterly
> wrong, wrong and wrong! :-P If the design stands as it is, I
> better write my own. But it won't get my vote.
FWIW, I have a use case in which a single function is used for all the
cases, but it doesn't seem monolithic. Structurally it is very
similar to the example given in the proposed library's documentation -
the case function looks something like this:
// get_port_c behaves similarly to fusion::at_c
// port_t<T> is a run-time polymorphic class derived from port
// the goal of this whole thing is to return a port * (port is the
base class of a run-time polymorphic class hierarchy) from an object
of some type T (T is required to model a certain concept - Port)
typedef void result_type;
void operator()(Case) const
get_port_case(Component& c, std::auto_ptr<port> &ret) : c(c), ret(ret)
It is used like this (the number of ports is known at compile time but
not at "coding time"):
std::auto_ptr<port> get_port(Component &c, int port_num)
boost::switch_<range>(port_num, detail::get_port_case<Component>(c, ret));
"A" seems ideal for this use case. I have trouble seeing how to use
"B" for it (easily) without making it so that the index is passed to
the function object and allowing something like case<range>(...). But
I might not be seeing all the possibilities. How can I implement this
Regardless of this example, if there isn't a "one size fits all"
interface that can be implemented in a lightweight enough fashion to
* should the Switch library provide both interfaces in separate
functions (even if they are both implemented with their own PP)?; or
* maybe the submitted library should have a different name/more
clearly stated scope, as Tobias has suggested?
Kudos to all of you for trying so hard at finding a solution for this!
Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk