简体   繁体   中英

Is there an alternative to input a enumerated type variable rather than using a static_cast

I was trying to input an enumerated type variable but i could not do it without a using a static_cast operation

#include<iostream>
using namespace std;

enum month
{
    JAN,
    FEB,
    MAY,
    JUNE,
    OCTOBER,
    DECEMBER,
};
int main()
{
    month This;
    cin >> This; <<_______________________ Causes a compiler error
    system("pause");
    return 0;
}

One workaround is to read in an integer, and use a static_cast to force the compiler to put an integer value into an enumerated type

{
int input_month;
cin >> input_month;

month This = static_cast<month>(input_month);<<_____________Works
}

So is there an alternative to inputting an enumerated type value

Here is an example how I would approach this (extending the answer of jacobi).

#include <iostream>
#include <stdexcept>

enum month
{
    JAN,
    FEB,
    MAY,
    JUNE,
    OCTOBER,
    DECEMBER,
};

month int2month(int m)
{
    switch(m)
    {
        case 1: return month::JAN;
        case 2: return month::FEB;
        case 3: return month::MAY;
        case 6: return month::JUNE;
        case 10: return month::OCTOBER;
        case 12: return month::DECEMBER;
        default: throw std::invalid_argument("unknown month");
    }
}

std::istream& operator>>(std::istream& is, month& m)
{
    int tmp;
    if (is >> tmp)
        m = int2month(tmp);
    return is;
}

int main()
{
    month This;
    try{
       std::cin >> This;
    }
    catch(std::invalid_argument& e){
    // TODO: handle
    }
    return 0;
}

online example

Notice that there are many more way how you could map 'int's to month. For example I think your code will give the same results as:

month int2month(int m)
{
    switch(m)
    {
        case 0: return month::JAN;
        case 1: return month::FEB;
        case 2: return month::MAY;
        case 3: return month::JUNE;
        case 4: return month::OCTOBER;
        case 5: return month::DECEMBER;
        default: throw std::invalid_argument("unknown month");
    }
}

Out of scope for this question:

Also note that you could write an 'string2month' function. Then you could make 'tmp' an string. Depending on 'tmp' containg only digits, you could convert 'tmp' to an 'int' to convert this to an month, or try to convert 'tmp' to an 'month'. This would allow for inputs like JAN or January, depending on the implementation of 'string2month'.

You would have to implement your own operator >> for the enum 'month' to do what you want.

Example:

std::istream& operator>>(std::istream& is, month& m)
{
    int tmp;
    if (is >> tmp)
        m = static_cast<month>(tmp);
    return is;
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM