Mixing static and dynamic polymorphism
Suppose I have an abstract Base class (with a pure virtual function)
and subclasses Derived1 and Derived2. Suppose I also have this:
template <class T>
class DerivedProperty; // DerivedProperty<Base> is
undefined
template <>
class DerivedProperty<Derived1> : public boost::true_type;
template <>
class DerivedProperty<Derived2> : public boost::false_type;
Now suppose I have these:
void foo(const boost::shared_ptr<Base>& ptr);
template <bool propertyValue>
class FooHelper; // Different specializations
for both true and false
What I want to do is, within foo(), is to create the appropriate
FooHelper based on the appropriate DerivedProperty::value and call a
virtual function (these two may or may not have any relation to each
other). Clearly, this cannot be done as-is, since within foo() I have
no data on whether this is a Derived1 pointer, a Derived2 pointer, or
some other pointer to a subclass of Base. (The issue of passing in a
pointer to a subclass of Base for which DerivedProperty::value isn't
defined isn't addressed at this point, since its resolution I believe
will depend on how this is redesigned. However, assume that this will
never be the case.)
If foo() was instead written like so:
template <class T>
void foo(const boost::shared_ptr<T>& ptr);
Then the drawback is that it would appear that I cannot, say, take a
homogeneous container like std::vector<boost::shared_ptr<Base>> and
call foo() on each pointer therein (which I do in my application)
without getting back to square one (since DerivedProperty<Base> is not
defined). The same reasoning would also eliminate a CRTP refactoring
of Base, I would assume.
Another thing I've been trying to do is perhaps instead add a function
to Base that does return DerivedProperty::value whenever it exists and
is well-defined. So I have the following to that effect:
class Base {
struct PropertyHolderBase {
virtual bool hasProperty() const = 0;
};
template <class Derived>
struct PropertyHolder : public PropertyHolderBase {
bool hasProperty() const { return
DerivedProperty<Derived>::value; }
};
boost::shared_ptr<PropertyHolderBase> propertyHolder;
public:
template <class Derived>
Base(...) : propertyHolder(new PropertyHolder<Derived>()) {}
bool hasProperty() const { return propertyHolder.hasProperty(); }
};
However, this would effectively force DerivedProperty to be defined for
every subclass of Base, which I might not want (perhaps there is a
subclass of Base where it isn't well-defined).
How do I resolve this?
--
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]