fork download
  1. #include <string>
  2. #include <vector>
  3. #include <map>
  4. #include <assert.h>
  5. #include <iostream>
  6.  
  7. using namespace std;
  8. class Variant{
  9. public:
  10. enum Type{
  11. INT,
  12. FLOAT,
  13. STRING
  14. };
  15. Variant(int i){
  16. m_type = INT;
  17. m_int = i;
  18. }
  19. Variant(float f){
  20. m_type = FLOAT;
  21. m_float = f;
  22. }
  23. Variant(const string &s){
  24. m_type = STRING;
  25. m_string = s;
  26. }
  27.  
  28. Type m_type;
  29. int m_int;
  30. float m_float;
  31. string m_string;
  32. };
  33.  
  34. class ArgList{
  35. public:
  36. template<class T>
  37. ArgList(const T &val){
  38. m_args.emplace_back(val);
  39. }
  40. template<class HEAD, class... TAIL>
  41. ArgList(const HEAD &head,const TAIL&... tail){
  42. m_args.emplace_back(head);
  43. ArgList t(tail...);
  44. m_args.insert(m_args.end(),t.m_args.begin(),t.m_args.end());
  45. }
  46.  
  47. vector<Variant> m_args;
  48. };
  49.  
  50. class ICommand{
  51. public:
  52. virtual void execute(const ArgList& args) = 0;
  53. template<class... ARGS>
  54. void executeList(const ARGS &... args){
  55. execute(ArgList(args...));
  56. }
  57. };
  58.  
  59. class Add : public ICommand{
  60. public:
  61. virtual void execute(const ArgList& args){
  62. assert(args.m_args.size() == 2);
  63. assert(args.m_args[0].m_type == Variant::INT);
  64. assert(args.m_args[1].m_type == Variant::INT);
  65. cout << "Add result:" << args.m_args[0].m_int + args.m_args[1].m_int << endl;
  66. }
  67. };
  68. class Negate : public ICommand{
  69. public:
  70. virtual void execute(const ArgList& args){
  71. assert(args.m_args.size() == 1);
  72. assert(args.m_args[0].m_type == Variant::INT);
  73. cout << "Negate result:" << -args.m_args[0].m_int<< endl;
  74. }
  75. };
  76.  
  77. class Print : public ICommand{
  78. virtual void execute(const ArgList& args){
  79. for(auto &var : args.m_args){
  80. switch(var.m_type){
  81. case Variant::INT:
  82. cout << "int " << var.m_int << ",";
  83. break;
  84. case Variant::FLOAT:
  85. cout << "float " << var.m_float << ",";
  86. break;
  87. case Variant::STRING:
  88. cout << "string " << var.m_string << ",";
  89. break;
  90. }
  91. }
  92. cout << endl;
  93. }
  94. };
  95. int main(){
  96. map<string,ICommand*> commands;
  97. commands["Add"] = new Add();
  98. commands["Negate"] = new Negate();
  99. commands["Print"] = new Print();
  100.  
  101. commands["Add"]->executeList(1,2);
  102. commands["Negate"]->executeList(4);
  103. commands["Print"]->executeList(1,2.0f,"helloworld!");
  104. }
Success #stdin #stdout 0s 3440KB
stdin
Standard input is empty
stdout
Add result:3
Negate result:-4
int 1,float 2,string helloworld!,