|
Boost Users : |
From: David Abrahams (dave_at_[hidden])
Date: 2005-05-01 10:01:25
"Delfin Rojas" <drojas_at_[hidden]> writes:
>> Not knowing what type of Foo it holds, how would you know what to do
>> with the result of getP? Its type depends on the type of the Foo.
>
> Yes, what I do with the result of getP would depend on the type of U. That
> is why I would need to get the right Foo<> back from FooBase *. Then I would
> pass this Foo<> through a template function that is specialized to a
> specific U and knows what to do with the result of getP().
In that case you're erasing the type information too early. You need
to instantiate the function template you mention above (call it f)
before you lose the type of Foo, e.g. make a vector of
shared_ptr<FooHolderBase>:
template <class T> void f(T*);
struct FooHolderBase
{
virtual ~FooHolderBase() {}
virtual void do_something_with_getP() = 0;
};
template <class U>
struct FooHolder
{
FooHolder(Foo<U> const& x) : held(x) {}
void do_something_with_getP()
{
f(held.getP()); // <== f gets instantiated
}
Foo<U> held;
};
template <class U>
void add_foo(
std::vector<boost::shared_ptr<FooHolderBase> > v
, Foo<U> const& x
)
{
v.push_back(
shared_ptr<FooHolderBase>(new FooHolder<U>(x))
);
}
There are various other ways to write this basic idiom (e.g. using
function pointers instead of building a class with virtual functions),
but the essential thing is that f<U> gets instantiated when you still
know U at compile-time.
If you try to erase the type first, you will end up with what is
essentially a massive type-switch:
type_info dynamic_type = typeid(*some_foo_base_ptr);
if (dynamic_type == typeid(Foo<A>))
f(*dynamic_cast<Foo<A>*>(some_foo_base_ptr));
else if (dynamic_type == typeid(Foo<B>))
f(*dynamic_cast<Foo<B>*>(some_foo_base_ptr));
...
which really sucks because it has to be maintained every time you
write Foo<U> for some new U.
HTH,
-- Dave Abrahams Boost Consulting www.boost-consulting.com
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