Boost logo

Boost :

From: Alexander Nasonov (alnsn_at_[hidden])
Date: 2002-11-11 11:45:58


Douglas Gregor wrote:

> On Monday 11 November 2002 08:32 am, Alexander Nasonov wrote:
>> Additionally, two types of control are desired:
>> 1) Control over real types of arguments. It is a limitation of
>> dynamic_any library that arguments must be converted to _one_ type before
>> a call. But they can be of different types. Problem can be easily solved
>> by adding additional arguments to the 'call' member-function:
>>
>> template<typename Arg>
>> bool less::call(const Arg & a, const std::type_info & ta,
>> const Arg & b, const std::type_info & tb) const
>> {
>> return a < b;
>> }
>
> I'm not sure I see why we need this functionality, but perhaps I'm not
> being imaginative enough at this hour. Do you have an example where this
> would help?

It was at the end of my post.
I know how it's hard to understand details without sufficient knowledge of
the topic. I tried to start documentation but it still unusable.

This functionality can be usefull but not quite often. I think it's better
to keep 'call' member function for simple use and introduce different name
(call_ex?) for advanced use. So, you can use one of:

  // 1)
  template<typename Arg>
  bool call(const Arg & a, const Arg & b) const;
  // 2
  template<typename Arg>
  bool call_ex(const Arg & a, const std::type_info & ta,
               const Arg & b, const std::type_info & tb) const;

Implementation can first try to call 'call_ex' and if it throws internal
exception (default behavoir) then revert to 'call' member-function.

Some further thoughts and questions.
1. Support for N-unary functions (currently N=1,2). With increase of N
complexity is aslo increased. Imagine that you have N 'any' arguments a1
... aN that hold values v1 ...vN of type T1 .. TN and you would like to
call a foo defined as:

  struct foo : function<foo, void (const arg &, ...., const arg &)>
                               // 'const arg &' repeated N times
  {
    template<class Arg>
    void call_ex(const Arg & v1, const std::type_info &,
                 ...
                 const Arg & vN, const std::type_info &) const
    {
      // user defined implementation
    }
  };

Current algorithm takes first argument a1 (which holds value v1 of type T1)
and tries to extract T1 & from a2 ... aN. If all extractions are ok then
invoke the foo:

  foo & func = ...
  func.call_ex(v1, typeid(v1),
               extract<T1 &>(a2), a2.type(),
               ...
               extract<T1 &>(aN), aN.type());
Otherwise apply the same to a2, ... aN arguments.
Remember that every extract uses dynamic_cast for a hierarchy with multiple
inheritance. Even for small N it can be expensive. Though some optimization
can be made IMHO.

2. Code bloat caused by generation of class hierarchy for every holded type.
This hierarchy is central to implementation and cannot be changed to
something else (but number of virtual functions can be minimized). The only
way is to teach users minimalizm in the library usage.

3. Integration with other libraries such as Serialization, variant and
visitor libraries.

Best regards,
Alexander Nasonov
mailbox: alnsn
server: mail.ru


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