Boost logo

Boost Users :

From: scleary_at_[hidden]
Date: 2001-11-09 10:14:48


> any is really a powerful class, but sometimes I would also be
> able to know directly the type stored into it without 'guessing', for
> example to use it in template code.
> What I would like to have is something as
>
> type_info::real_type for the value hidden into any (not legal
> C++, maybe
> legal C++0x ?),

This actually wouldn't help you, still. How would the declaration look?
typeof() wouldn't work, either...

> or, alternatively, virtual template functions (again not
> legal C++) to be
> able to write generic
> code depending on both hidden value's type and types 'from the outside
> world' (sorry cannot explain it better :-( than this)

I have run into this same problem. To re-phrase it, Gianni is trying to do
an "operation" on a contained value. 'any' supports the "operations" of
copying and destruction as-is; manual modification of 'any' could support
other "operations" (this is what Gianni means when he talks about "visiting"
the any class, below):
  any { ... void f() { if (content) content->f(); } };
  any::placeholder { ... virtual void f() = 0; };
  any::holder<...> ... { ... virtual void f() { held.f(); } };

The problem is how to do this generically (i.e., provide a solution for any
"operation").

Another way of looking at this is to force 'any' to call a function that is
overloaded on the type of the contained value.

Strictly speaking, this isn't possible because 'any' makes the compile-time
info into run-time info.

> I have tried various approaches, but if I 'visit' the any
> class adding a
> virtual function to reach hidden value I loose generic type
> information
> (lack of virtual template functions) from the outside while from the
> outside of any
> I cannot obtain directly the type of the hidden value ...
>
> is there a way to do the above ?

I have not been successful. Again, 'any' changes compile-time information
into run-time information, and to go the other way is just not possible in
this language.

You could take a "nasty-hack" approach, if you *really* wanted to:
  1) Add an 'any_base' class with a virtual function
  2) Extend 'any' to return an 'any_base *' referring to the held value,
using C-cast notation (derived-to-base when possible, reinterpret when not)
  3) Derive your held value types from a common base class 'my_base', which
was derived from 'any_base'; add the operations you want to perform to
'my_base'
  4) Call the 'any' function returning 'any_base *', downcasting it to
'my_base'. This will result in undefined behaviour if the contained value
is not actually derived from 'my_base' (because of the reinterpret_cast
behaviour in step 2)

I *think* that will work (never tried it). Messy, though, and IMO not
generic enough to mess with.

Alternatively, you could:
  1) Visit 'any'/'any::placeholder'/'any::holder' to provide:
     void any::action(any which) { content->action(which); }
     virtual void any::holder::action(any which) { any_action(held, which);
}
  2) Declare a function 'any_action(T, any)', where the any parameter
designates which "operation" to perform. Overloading is then possible on T.
Also, where T is a user-defined type, Koenig lookup can be used (abused?) to
create different (non-overlapping) sets of "operations".

Just some thoughts. Again, I've never tried it.

        -Steve


Boost-users list run by williamkempf at hotmail.com, kalb at libertysoft.com, bjorn.karlsson at readsoft.com, gregod at cs.rpi.edu, wekempf at cox.net