C++来自 char 的枚举

发布于 2024-08-02 10:15:33 字数 1635 浏览 5 评论 0原文

好的,我是 C++ 新手。我拿到了 Bjarne 的书,我正在尝试遵循计算器代码。

然而,编译器正在吐出关于此部分的错误:

token_value get_token()
{
    char ch;

    do {        // skip whitespace except '\n'
        if(!std::cin.get(ch)) return curr_tok = END;
    } while (ch!='\n' && isspace(ch));

    switch (ch) {
        case ';':
        case '\n':
            std::cin >> WS;      // skip whitespace
            return curr_tok=PRINT;
        case '*':
        case '/':
        case '+':
        case '-':
        case '(':
        case ')':
        case '=':
            return curr_tok=ch;
        case '0': case '1': case '2': case '3': case '4': case '5':
        case '6': case '7': case '8': case '9': case '.':
            std::cin.putback(ch);
            std::cin >> number_value;
            return curr_tok=NUMBER;
        default:            // NAME, NAME=, or error
            if (isalpha(ch)) {
                char* p = name_string;
                *p++ = ch;
                while (std::cin.get(ch) && isalnum(ch)) *p++ = ch;
                std::cin.putback(ch);
                *p = 0;
                return curr_tok=NAME;
            }
            error("bad token");
            return curr_tok=PRINT;
}

它吐出的错误是这样的:

calc.cpp:42: error: invalid conversion from ‘char’ to ‘token_value’

token_value是一个枚举,看起来像:

enum token_value {
    NAME,       NUMBER,     END,
    PLUS='+',   MINUS='-',  MUL='*',  DIV='/',
    PRINT=';',  ASSIGN='=', LP='(',   RP=')'
};
token_value curr_tok;

我的问题是,如何转换ch(来自cin),到关联的枚举值?

Ok, I'm new at C++. I got Bjarne's book, and I'm trying to follow the calculator code.

However, the compiler is spitting out an error about this section:

token_value get_token()
{
    char ch;

    do {        // skip whitespace except '\n'
        if(!std::cin.get(ch)) return curr_tok = END;
    } while (ch!='\n' && isspace(ch));

    switch (ch) {
        case ';':
        case '\n':
            std::cin >> WS;      // skip whitespace
            return curr_tok=PRINT;
        case '*':
        case '/':
        case '+':
        case '-':
        case '(':
        case ')':
        case '=':
            return curr_tok=ch;
        case '0': case '1': case '2': case '3': case '4': case '5':
        case '6': case '7': case '8': case '9': case '.':
            std::cin.putback(ch);
            std::cin >> number_value;
            return curr_tok=NUMBER;
        default:            // NAME, NAME=, or error
            if (isalpha(ch)) {
                char* p = name_string;
                *p++ = ch;
                while (std::cin.get(ch) && isalnum(ch)) *p++ = ch;
                std::cin.putback(ch);
                *p = 0;
                return curr_tok=NAME;
            }
            error("bad token");
            return curr_tok=PRINT;
}

The error it's spitting out is this:

calc.cpp:42: error: invalid conversion from ‘char’ to ‘token_value’

token_value is an enum that looks like:

enum token_value {
    NAME,       NUMBER,     END,
    PLUS='+',   MINUS='-',  MUL='*',  DIV='/',
    PRINT=';',  ASSIGN='=', LP='(',   RP=')'
};
token_value curr_tok;

My question is, how do I convert ch (from cin), to the associated enum value?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

摇划花蜜的午后 2024-08-09 10:15:33

您不能从 char 隐式转换为 enum - 您必须显式执行此操作:

return curr_tok = static_cast<token_value> (ch);

但要小心!如果您的 enum 值都不与您的 char 匹配,那么将很难使用结果:)

You can't implicitly cast from char to an enum - you have to do it explicitly:

return curr_tok = static_cast<token_value> (ch);

But be careful! If none of your enum values match your char, then it'll be hard to use the result :)

傾城如夢未必闌珊 2024-08-09 10:15:33

请注意,给出的解决方案(即告诉您使用static_cast)只能正常工作,因为当定义枚举符号时,符号(例如PLUS)被定义为具有物理/数字值恰好等于底层字符值(例如'+')。

另一种方法(不使用强制转换)是使用 switch/case 语句显式指定为每个字符值返回的枚举值,例如:

    case '*':
      return curr_tok=MUL;
    case '/':
      return curr_tok=DIV;

Note that the solutions given (i.e. telling you to use a static_cast) work correctly only because when the enum symbols were defined, the symbols (e.g. PLUS) were defined to have a physical/numeric value which happens to be equal to the underlying character value (e.g. '+').

Another way (without using a cast) would be to use the switch/case statements to specify explicitly the enum value returned for each character value, e.g.:

    case '*':
      return curr_tok=MUL;
    case '/':
      return curr_tok=DIV;
离鸿 2024-08-09 10:15:33

您需要显式转换:

curr_tok = static_cast<token_value>(ch);

原因是将整数类型转换为枚举是危险的。如果该值对于枚举无效,则行为未定义。因此,该语言不会让您意外地进行隐式转换。显式转换应该意味着“我知道我在做什么,并且我已经检查了该值是否有效”。

You need an explicit cast:

curr_tok = static_cast<token_value>(ch);

The reason is that it's dangerous to convert an integer type to an enum. If the value is not valid for the enum then behaviour is undefined. So the language doesn't let you do it accidentally with an implicit conversion. The explicit conversion is supposed to mean "I know what I'm doing, and I've checked that the value is valid".

暮色兮凉城 2024-08-09 10:15:33

我想我不会尝试显式设置枚举符号的值,而是为 switch 语句中的每个符号编写一个案例。如果出现问题,这样做可能会更难调试,并且为每个符号编写案例的性能成本非常低,甚至不值得考虑(除非您正在为某种极低端的嵌入式系统编写代码)并且可能仍然不值得)。

I think I wouldn't try to explicitly set the values of the enum symbols and instead write a case for every symbol that in your switch statement. Doing it that way will probably be harder to debug if something goes wrong and the performance cost writing a case for every symbol is so low, that it's not even worth considering (unless you're writing for some kind of extremely low-end embedded system and probably still not worth it).

变身佩奇 2024-08-09 10:15:33
return curr_tok=(token_value)ch;
return curr_tok=(token_value)ch;
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文