Boost logo

Boost :

From: Gennadiy Rozental (gennadiy.rozental_at_[hidden])
Date: 2004-11-21 21:21:12


> > Wait, this is an exact copy of an example you have in "controlling
overload
> > resolution" section. Any why two functions then?
>
> I'm sorry, I don't know what that means.
>
> > So can you gove me an example of "controlling overload resolution"
feature?
>
> I just did. foo is enabled only when 'name' is convertible to char
> const*.

No. this is an example of type restriction. Overload resolution assimes at
least 2 overloads, doesn't it?

> > First of all this is comparatevly rarely needed. Accordingly I do not
see a
> > reasons to supply library solution for this problem.
>
> So we shouldn't care about this use case? Why? To reduce the number of
> lines of code in the implementation?

No. I just don't think it belong to this library at all. Especially if it's
easier to implement without library.

> > Whould I ever need
> > something like this, I would do:
> >
> > template<typename Value>
> > enable_if<Value is movable,void>
> > foo_impl( Value const&, std::string name, Mymode mode )
> > {
> > }
> >
> > template<typename Params>
> > void foo(Params const& p)
> > {
> > foo_impl( p[value], p[name], p[mode] );
> > }
> >
> > value above is typelees keyword in my terminology. And no need to mix
> > everything into one bowl.
>
> But again, you don't generally have the ability to have a universal
> foo() overload that handles the dispatching. You want one for every
> overload.

You keep pressing that there maybe more that one foo. Why would I want to do
this? Could you give an example?

In my POV I onlt need one
foo(Params const& p )

since it automatically cover all possible invokcation of function foo.

> > This is not exactly the same thing, and clear source of confusion.
>
> Really? What's the difference?

Difference is this 8 out of 10 developers would ask where this 0 comes from?
And what does it mean? 2 out of 10 wouldn't understant this code at all.

> > Ok. So what is your solution to the problem of supplying single named
> > parameter based interface for dynamically sized series of functions with
> > different actual number of arguments?
>
> I would add something to the library to control overload resolution for
> this case with SFINAE.

I am getting an impression that you don't have even vague idea how would it
look like. Could you come up at least with some pseudo code?

> > Why is that? Why Couldn't I do the same as what you are doing?
> >
> > int v = params.has(a) ? params[a] : get_a_default_value();
> >
> > It's even easier since I do not need to wrap it into bind call.
>
> No, because get_a_default_value() has to compile. Our defaults can be
> lazily evaluated, and only compiled when needed.

Here is your code:

  double value_default()
  {
      return 666.222;
  }

  template<class Params>
  int f_impl(const Params& p)
  {
      p[tester]( p[name], p[value || boost::bind(&value_default) ] );
  }

Here is mine:

  double value_default()
  {
      return 666.222;
  }

  template<class Params>
  int f_impl(const Params& p)
  {
      p[tester]( p[name], p.has(value) ? p[value] : value_default() );
  }

In both cases default_value() needs to be compiled. Why my syntax is way
better IMO.

> >>Really? Is the parameter defaults also an implementation detail? As a
> >>user, how am I suppose to use your functions if I don't know about these
> >>things?
> >
> >
> > Yes. I inclined to think about function parameter default values more in
> > terms of implementation details rather than part of interface. You as a
> > function user shouldn't based your decisions on the default value for
the
> > parameter: you have value for this parameter - you supply it. You
don't -
> > function deals with it itself. This is especially true since in many ,
many
> > cases you just couldn't put default value into function declaration:
> >
> > int foo( int a, int b = a ) {...}
> >
> > What we do instead is somehow mimic similar behavior:
> >
> > int foo( int a, int b = -1 ) {
> > if( b = -1 )
> > b = a;
> > }
> >
> > So what default value -1 gives you as a function caller?
>
> The value of 'a'?

And how caller should know that? And most importantly why?

> What you were arguing here however is that it shouldn't even be part of
> the interface whether 'b' has a default value or is a required
> parameter.

In legacy C+ there are areseveral ways to make b "optional"

.., int b = 2
..., int b = invalid_value
..., int* b
..., optional<int> b = optional<int>()

The only thing that is important is the fact that b is optional. This is
interface part. The default value (if needed) is implementation detail. In
my solution I mark keywords whether or not they name optional or requied
parameters.

> > How? I would like to see it. I would like to see you to produce compile
time
> > error based on runtime value of the variable.
>
> Of course I can't produce compile time errors based on runtime values,
> but who said anything about mode being a runtime value? The modes could
> just as well be tag types here, in which case it's trivial.

In many cases it's not acceptable.

> template<class P>
> int select_impl(wait_t, P const& args) ..
>
> template<class P>
> int select_impl(block_t, P const& args) ..
>
> template<class P>
> int select_impl(pool_t, P const& args) ..
>
> template<class P>
> int select(P const& args)
> {
> return select_impl(args[mode], args);
> }

Hey! Where is optional timeout handling? You code wouldn't compile if timeut
is missing.

> --
> Daniel Wallin

Gennadiy


Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk