【问题标题】:C++ enum from char来自 char 的 C++ 枚举
【发布时间】:2009-08-19 01:17:01
【问题描述】:

好的,我是 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)转换为关联的枚举值?

【问题讨论】:

    标签: c++ enums char


    【解决方案1】:

    您不能从 char 隐式转换为 enum - 您必须明确地这样做:

    return curr_tok = static_cast<token_value> (ch);
    

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

    【讨论】:

      【解决方案2】:

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

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

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

      【讨论】:

        【解决方案3】:

        你需要一个明确的演员:

        curr_tok = static_cast<token_value>(ch);
        

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

        【讨论】:

          【解决方案4】:

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

          【讨论】:

            【解决方案5】:
            return curr_tok=(token_value)ch;
            

            【讨论】:

            • 在使用 C++ 而不是 C 时,更喜欢使用新式强制转换(即static_cast 等)。
            • 或者,如果您确实想使用 C 风格的强制转换,请使用构造函数语法将它们隐藏起来:curr_tok = token_value(ch)。您的样式指南的作者在禁止单参数构造函数之前可能会三思而后行,即使它们只能使用 C 样式强制转换来调用。 ;-)
            猜你喜欢
            • 1970-01-01
            • 2011-03-15
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2012-07-07
            • 1970-01-01
            • 1970-01-01
            相关资源
            最近更新 更多