How do I get around this? I clearly cannot make the value() method virtual as I won't know what type it is beforehand, and may not know this when accessing the method from b:
class Base
{
public:
Base() { }
virtual ~Base() { }
private:
int m_anotherVariable;
};
template <typename T>
class Derived : public Base
{
public:
Derived(T value) : m_value(value) { }
~Derived() { }
T value() { return m_value; }
void setValue(T value) { m_value = value; }
private:
T m_value;
};
int main()
{
Base* b = new Derived<int>(5);
int v = b->value();
return 0;
}
Compilation errors:
error: 'class Base' has no member named 'value'
This statement:
int v = b->value();
The variable 'b' is being trated like it is an object of Derived<int>.
So tell the compiler:
int v = dynamic_cast<Derived<int>*>(b)->value();
Note: If b is not a Derived<int> the result of the cast is NULL.
So the following would probably be safer:
Derived<int>* d = dynamic_cast<Derived<int>*>(b);
if (d)
{
int v = d->value();
}
else
{
// Error
}
Alternatively by using references you get a bad_cast exception thrown:
// Throw bad_cast on failure.
Derived<int>& d = dynamic_cast<Derived<int>&>(*b);
int v = d->value();
Or to be nice and obscrure we can do it one line.
// Assign v or throw bad_cast exception:
int v = dynamic_cast<Derived<int>&>(*b).value();
But I think you can achieve what you are trying to do with the boost::any
int main()
{
boost::any b(5);
int v = boost::any_cast<int>(b);
b = 5.6; // double
double d = boost::any_cast<double>(b);
}