2009-08-19 19 views
5

Ok、私はC++の新機能です。私はBjarneの本を手に入れました。私は電卓のコードに従おうとしています。C++ enum from char

しかし、コンパイラは、このセクションに関するエラーを吐き出している:

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から)を関連する列挙型に変換する方法です値?

答えて

7

あなたは暗黙的にenumcharからキャストすることはできません - あなたは、明示的にそれをしなければならない。

return curr_tok = static_cast<token_value> (ch); 

しかし、注意してください!あなたのenum値のどれもがあなたのcharと一致しない場合、結果を使用するのは難しいだろう:)

1

あなたは明示的なキャストが必要です。

curr_tok = static_cast<token_value>(ch); 

を理由は、整数型に変換するのは危険だということですエニュムに値が列挙型に対して有効でない場合、動作は未定義です。つまり、暗黙の変換で誤ってやることはありません。明示的な変換は、「私がやっていることを知っていて、その値が有効であることを確認しました」という意味です。

-1
return curr_tok=(token_value)ch; 
+2

Cの代わりにC++を使用するときは、新しいスタイルのキャスト(static_castなど)を使用することをお勧めします。 – ChrisW

+0

またはCスタイルのキャストを使用する場合は、コンストラクタ構文を使用してレーダーの下にスニークします: 'curr_tok = token_value(ch) '。スタイルガイドの作者は、単一引数のコンストラクタを禁止する前に、たとえCスタイルのキャストを使用して呼び出すことができるにしても、2度考えるかもしれません。 ;-) –

4

static_castを使用するためにあなたを伝えるすなわち)指定されたソリューションがenumシンボルが定義されていたとき、記号(例えば​​が)に起こる物理/数値を持つように定義されていたという理由だけで正常に動作することを注意基礎となる文字の値(例えば、'+')と等しくなります。

(キャストを使用せずに)別の方法としては、例えば、列挙型の値は、各文字の値に対して返さ明示的に指定するには、スイッチ/ case文を使用することです:

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

私は私がしようとしないだろうと思います明示的にenumシンボルの値を設定し、代わりにswitch文にあるすべてのシンボルの大文字と小文字を書き込みます。このようにすれば、何かがうまくいかず、すべてのシンボルのケースを書くパフォーマンスコストが非常に低く、考慮すべき価値がない(たとえ何らかの極端なローエンドの組み込みシステム用に書かない限り)おそらくまだそれに値するわけではない)。