RE: [Boost-Users] question about any class ...
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
On Fri, 9 Nov 2001 scleary@jerviswebb.com wrote: [ SNIP ]
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.
I will try it, but it seems to me that this approach doesn't solve the problem 'cause from any_base I cannot know the type of the contained value; this type, infact is derived from any_base ... :-(
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".
I don't understand this completely, but I think the core point is the set of overloaded functions ... so I should add an overloaded fun for every type I need ... seems a big loss of genericity to me :-(
Just some thoughts. Again, I've never tried it. However they are interesting: many thanks for Your ideas
I also try to restate my needs: I would like to be able to simulate the
following code fragment that uses virtual template funcs (but I started
thinking it's impossible):
class any{
...
template <typename newtype> void * cast_to()
{ if(ptr) ptr->cast_to<newtype>(); }
...
class placeholder{
...
virtual template <newtype> void * cast_to() = 0;
};
template <typename value_type>
class holder : public placeholder{
...
virtual template <newtype> void * cast_to(){
// * here I know both value_type AND newtype *
return dynamic_cast
participants (2)
-
Gianni Luciani
-
sclearyï¼ jerviswebb.com