I'm not sure if this is what you want, but I will continue what I came up with:
A small metaprogram to find the type in the list of types / variables list. It is necessary to determine whether the team is part of the implementation or not.
namespace meta { template <typename... T> struct list{}; template <typename F, typename T> struct has_type; template <typename F> struct has_type<F, list<>> { using type = typename std::false_type; static constexpr bool value = false; }; template <typename F, typename... T> struct has_type<F, list<F, T...>> { using type = typename std::true_type; static constexpr bool value = true; }; template <typename F, typename H, typename... T> struct has_type<F, list<H,T...>> { using type = typename std::false_type; static constexpr bool value = std::is_same<F, typename std::decay<H>::type>::value ? true : has_type<F, list<T...>>::value; }; }
Now define your teams having a common base class:
struct CommandBase {}; struct CommandA: CommandBase {}; struct CommandB: CommandBase {}; struct SomeCommandType: CommandBase {}; struct CommandC: CommandBase {}; using AvailableCommmands = meta::list<CommandA, CommandB, SomeCommandType>;
The AvailableCommmands type determines for which type the not implemented message should appear. If a particular coomand type is not available in AvailableCommmands meta :: list, then a message should be printed for this type not implemeneted .
The rest of the code (base + derivative):
class Base { public: template <typename T> void on_modify_command(T cmd) { do_on_modify_command(cmd, typename meta::has_type<T, AvailableCommmands>::type()); } private: virtual void do_on_modify_command(CommandBase&, std::true_type) = 0; virtual void do_on_modify_command(CommandBase& b, std::false_type) { std::cout << "Not implemented" << std::endl; } }; class Derived: public Base { public: void do_on_modify_command(CommandBase& cmd, std::true_type) { std::cout << "Specialized command implementation" << std::endl; impl(*static_cast<SomeCommandType*>(&cmd)); } void impl(SomeCommandType cmd) { std::cout << "huh!!" << std::endl; } }; int main() { CommandA ca; Base* b = new Derived; b->on_modify_command(ca); CommandC cc; b->on_modify_command(cc); return 0; }
The code is messy, I'm sure there must be some better way to do this.