#include <iostream>

enum COMMANDS {
    CMD_ZERO,
    CMD_ONE,
    CMD_TWO,
};

template <COMMANDS cmd> struct command
{
    template <typename ... Args>
    int operator() (Args&&...) const { return -1; }
};

template <> struct command<CMD_ZERO>
{
    int operator()(double a, double b, double c) const
    {
        std::cout << "cmd0  " << a << ", " << b << ", " << c << std::endl;
        return 0;
    }
};

template <> struct command<CMD_ONE>
{
    int operator()(int a, int b, int c) const
    {
        std::cout << "cmd1  " << a << ", " << b << ", " << c << std::endl;
        return 1;
    }
};

template <COMMANDS cmd, typename... Args> int DispatchCommand(Args&&... args)
{
    return command<cmd>()(std::forward<Args>(args)...);
}

int main()
{
    DispatchCommand<CMD_ZERO>(1, 3.141, 4);
    DispatchCommand<CMD_ONE>(5, 6, 7);
    DispatchCommand<CMD_TWO>(5, 6, 7, 8, 9);
    return 0;
}
