converting from int to enum

后端 未结 4 1341
渐次进展
渐次进展 2021-01-20 08:31

I have declared the following enum :

  enum periods {one, five, ten, fifteen, thirty};

and now I want to pass it as a commandline argument

4条回答
  •  逝去的感伤
    2021-01-20 09:20

    The straightforward solution is to use static_cast (as the other answer has already posted it):

    periods mp;
    if (argc == 2)
    {
       std::string min_prd(argv[1]); //the index should be 1
       mp = static_cast(atoi(min_prd.c_str()));
    }
    

    But then atoi should not be used to convert the c-string into int, because atoi doesn't check for error in the input string, hence it is unsafe.

    C++11 provides safer conversion functions, so you could use std::stoi as:

    try
    {
       periods mp;
       if (argc == 2)
       {
          //std::stoi could throw exception on error in input
          mp = static_cast(std::stoi(argv[1]));
       }
       //use mp here
    }
    catch(std::exception const & e)
    {
       std::cout << "exception caught with message : " << e.what() << std::endl;
    }
    

    Now that is a better solution.


    However, there is an alternative solution which you could use as:

    period mp;
    if (argc == 2)
    {
       mp = to_period(argv[1]); //how should we implement it?
       if (mp == period_end)
       {
           std::cout << "command line input error" << std::endl;
           return 0;
       }
    }
    

    Now the question is, how should we implement to_period function?

    Note that this solution assumes that the command line argument for enum value one would be its string representation, i.e it would be "one" instead of 1 which is integral representation.

    I would implement this solution as:

    • First create a header file called period_items.h as:

      //period_items.h
      E(one)
      E(five)
      E(ten)
      E(fifteen)
      E(thirty)
      
    • then create another header file called period.h as:

      //period.h
      #include 
      
      enum period 
      {
         #define E(item)  item,
           #include "period_items.h"
         #undef E
         period_end
      };
      
      period to_period(std::string const & name)
      {
         #define E(item)  if(name == #item) return item;
           #include "period_items.h"
         #undef E
         return period_end;
      }
      

    Now you can simply include period.h and use to_period function. :-)

    Note that in the alternative solution, I've used singular form rather than plural form, means I've used period rather than periods. I feel period is appropriate.

    You could also add this function to period.h as:

    std::string to_string(period value)
    {
        #define E(item)  if(value == item) return #item;
            #include "period_items.h"
        #undef E
        return "";
    }
    

    Now, you could write this:

    #include "period.h"
    
    period v = to_period(argv[1)); //string to period
    std::string s = to_string(v);  //period to string
    

    Hope that helps.

提交回复
热议问题