2009-08-19 35 views
5

Ok, tôi mới ở C++. Tôi nhận được cuốn sách của Bjarne, và tôi đang cố gắng làm theo mã máy tính.C++ enum từ char

Tuy nhiên, trình biên dịch được phun ra một lỗi về phần này:

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; 
} 

Các lỗi nó phun ra là thế này:

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

token_value là một enum mà trông giống như:

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

Câu hỏi của tôi là, làm cách nào để chuyển đổi ch (từ cin) sang enum được liên kết giá trị?

Trả lời

7

Bạn không thể ngầm đúc từ char một enum - bạn phải làm điều đó một cách rõ ràng:

return curr_tok = static_cast<token_value> (ch); 

Nhưng hãy cẩn thận! Nếu không ai trong số enum giá trị của bạn phù hợp với char của bạn, sau đó nó sẽ khó có thể sử dụng kết quả :)

1

Bạn cần một diễn viên rõ ràng:

curr_tok = static_cast<token_value>(ch); 

Lý do là nó nguy hiểm để chuyển đổi một kiểu số nguyên đến một enum. Nếu giá trị không hợp lệ cho enum thì hành vi là không xác định. Vì vậy, ngôn ngữ không cho phép bạn làm điều đó một cách vô tình với một chuyển đổi ngầm định. Chuyển đổi rõ ràng được cho là có nghĩa là "Tôi biết tôi đang làm gì và tôi đã kiểm tra xem giá trị có hợp lệ không".

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

Ưu tiên sử dụng phôi kiểu mới (ví dụ 'static_cast', v.v.) khi sử dụng C++ thay vì C. – ChrisW

+0

Hoặc nếu bạn muốn sử dụng phôi kiểu C, hãy lén chúng theo radar bằng cú pháp hàm dựng:' curr_tok = token_value (ch) '. Tác giả của hướng dẫn phong cách của bạn có thể suy nghĩ hai lần trước khi cấm các nhà xây dựng đối số đơn, mặc dù chúng chỉ có thể được gọi bằng cách sử dụng một dàn diễn viên kiểu C. ;-) –

4

Lưu ý rằng các giải pháp nhất định (ví dụ như mắng bạn sử dụng một static_cast) làm việc một cách chính xác chỉ bởi vì khi những biểu tượng enum được xác định, những biểu tượng (ví dụ PLUS) được xác định để có một giá trị vật chất/số đó xảy ra với bằng với giá trị ký tự cơ bản (ví dụ: '+').

Một cách khác (không sử dụng một dàn diễn viên) sẽ được sử dụng những điều khoản chuyển/trường hợp để xác định một cách rõ ràng enum giá trị trả về cho mỗi giá trị nhân vật, ví dụ:

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

Tôi nghĩ rằng tôi sẽ không cố gắng đặt rõ ràng các giá trị của các biểu tượng enum và thay vào đó viết một trường hợp cho mọi biểu tượng trong câu lệnh switch của bạn. Làm theo cách đó có thể sẽ khó khăn hơn để gỡ lỗi nếu xảy ra sự cố và chi phí hiệu suất viết một trường hợp cho mỗi biểu tượng quá thấp, thậm chí không đáng xem xét (trừ khi bạn viết cho một số loại hệ thống nhúng cực thấp và có lẽ vẫn không đáng giá).

Các vấn đề liên quan