From: Doug Gregor (gregod_at_[hidden])
Date: 2001-04-10 09:15:20


On Tuesday 10 April 2001 09:21, you wrote:
> > In any case, what definition of type-strictness are you using?
>
> Well, I prefer no conversion at all, so only functions that exactly
> match the signature are allowed. I can understand, though, that
> implicit conversions might be desirable, and casting is absolutely
> undesirable. It can be dangerous from time to time, though. e.g
> using 'char' when 'int' is required. In the current implementation
> of 'function', there's no protection against this. Maybe a policy
> could solve it...

This is no different from calling any other function. If I pass an int into a
char, the compiler will likely give a diagnostic. The same diagnostic will
occur with 'function'.

> > > > > > ------------------------------
> > > > > > Interface summary:
> > > > > >
> > > > > > template<typename Result, typename Arg1, typename Arg2,
> > > > > > ..., typename ArgN>
> > > > >
> > > > > The main problem with this approach is that it isn't extendable.
> > > > > I mean, how many parameters to support? as I view the code, it's
> > > > > implemented for up to 6 parameters, which is in my opinion enough
> > > > > (my 'previous version' had this approach for up to 5), but I
> > > > > guarantee you someone will require 7. The largest implementation
> > > > > I've seen so far is Alexandrescu's Functor class: a massive 15
> > > > > parameters (the one in Modern C++ Design).
> > > >
> > > > This argument has been made on this list in the past. Both sides
> > > > have valid arguments, IMHO, making this a very sticky design decision
> > > > to deal with.
> > >
> > > Hmm, the main problem with the current approach is that there's
> > > _no_ way to extended it with e.g. policies. For instance, whether
> > > or not to throw when no function attached. I mean, that would mess
> > > up the default Argx declaration. I wouldn't want to declare it like:
> > >
> > > function<
> > > void,
> > > int,
> > > detail::unusable,
> > > detail::unusable,
> > > detail::unusable,
> > > detail::unusable,
> > > nothrow
> > >
> > > > instance;
> > >
> > > Apart from undesirable, it now is impossible to add a new
> > > (a 7th) parameter.
> > >
> > > So I simply think doing it this way is wrong, but hey,
> > > that's just me...
> >
> > I mentioned a possible resolution to this that I intend to try soon. The
> > policy/trait/etc classes would use named parameters and a generative
> > interface. The crux of the idea is that the above would be written as:
> >
> > function<void, int>::nothrow instance;
> >
> > The underlying implementation would (possibly) be based on function0,
> > function1, ... classes that do the actual work.
>
> An interesting idea, though user-defined policies/traits is still
> a problem. Of course, -in this case- nothrow could be made a
> template receiving whatever is appropriate. For instance:
>
> function<void,int>::template exception<myException> instance;
>
> which would throw myException when no function is attached...

I'm failing to see the problem - a parameter could easily be named "policy"
or "traits" and take a trait class. A skeleton 'function' could look like
this:

template<typename R, typename T1, ..., typename TN>
class function : public typename get_function<R, T1, ..., TN>::type
{
  template<typename Policy>
  struct policy : public typename get_function<R, T1, ..., TN, Policy>::type
  {
    // ...
  };
};

Then we use as above:
function<int, float>::policy< ref_counted > instance;

(the "template" isn't needed because function<int, float> is not dependent on
any template types).

> > > One last thing: assigning a function will cause memory allocation.
> > > copy construction/assignment doesn't, because reference counting
> > > is used...
> >
> > This was also debated at length. There was an overall
> > preference for the cloning.
>
> I agree when no memory allocation is required (as for 'function'),
> then reference counting wouldn't really add anything.

Memory allocation is required for cloning function objects. Along with
policies/traits would come an allocator to give the user more control over
the allocation or, perhaps, allow them to choose reference conting.
        
        Doug