You could try the following in your class:
private:
template<typename T>
void visit(const Potion& potion)
{
// leave if unavailable action for various reasons
// and a few more things...
PotionAction* action = new T(potion);
actions.push_back(action);
// add to our button list
}
public:
virtual void visitUpper(const Potion& potion)
{
visit<UpperAction>(potion);
}
virtual void visitDowner(const Potion& potion)
{
visit<DownerAction>(potion);
}
// more visitXXX ...