Consider:
#include <vector>
#include <memory>
class Base {};
class Derived : public Base {};
template<typename T>
class Effect
{
public:
virtual void call(T& val) = 0;
// Additional Functions...
};
class BaseEffect : public Effect<Base>
{
public:
// Since Derived inherits from Base, we are able to pass Derived to BaseEffect
void call(Base& val) override { /*Code modifying Base*/ }
};
class DerivedEffect : public Effect<Derived>
{
public:
void call(Derived& val) override { /*Code modifying Derived*/ }
};
int main()
{
std::vector<std::unique_ptr<Effect<Derived>>> effects;
effects.emplace_back(std::make_unique<DerivedEffect>());
// Ugly and maybe undefined?
effects.emplace_back(reinterpret_cast<Effect<Derived>*>(new BaseEffect()));
Derived state;
effects[0]->call(state); // Executes DerivedEffect::call
effects[1]->call(state); // Executes BaseEffect::call
return 0;
}
I know that effects will never store the template-argument; They will only ever access it through function calls. But I can't use std::function since the Effect-class is more complicated than just having one function. Also, I don't want to use dynamic_cast in Effect::call, since it will be executed a lot.
So is my question is, is the reinterpret-cast safe, under my previous assumptions? Additionally, is there a cleaner way to achieve my goal, apart from creating a custom container that manages the vector?