2009-12-09 25 views
6

Gần đây tôi đã xem qua một số chức năng mà bạn có thể vượt qua nhiều enums như thế này:C++ nhiều enums trong một đối số hàm sử dụng bitwise hoặc "|"

myFunction(One | Two); 

Vì tôi nghĩ rằng đây là một cách thực sự tao nhã tôi cố gắng thực hiện một cái gì đó như thế bản thân mình:

void myFunction(int _a){ 
    switch(_a){ 
     case One: 
      cout<<"!!!!"<<endl; 
      break; 
     case Two: 
      cout<<"?????"<<endl; 
      break; 
    } 
} 

nay nếu tôi cố gọi hàm bằng One | Hai, tôi muốn cả hai trường hợp chuyển đổi được gọi. Tôi không thực sự tốt với các nhà khai thác nhị phân vì vậy tôi không thực sự biết phải làm gì. Bất cứ ý tưởng sẽ là tuyệt vời!

Cảm ơn!

+1

Đăng định nghĩa 'enum' của bạn .. bạn có nhớ đặt tất cả các quyền đó thành 2 không? – eduffy

+1

Lưu ý tên _a được dành riêng cho việc thực hiện C++, trừ khi nó là tên của một thành viên lớp. –

Trả lời

11

Cho rằng bạn cần phải thực hiện enums như:

enum STATE { 
    STATE_A = 1, 
    STATE_B = 2, 
    STATE_C = 4 
}; 

ví dụ: enum giá trị phần tử phải ở trong sức mạnh của 2 để chọn trường hợp hợp lệ hoặc câu lệnh if.

Vì vậy, khi bạn làm thích:

void foo(int state) { 

    if (state & STATE_A) { 
    // do something 
    } 

    if (state & STATE_B) { 
    // do something 
    } 

    if (state & STATE_C) { 
    // do something 
    } 
} 

int main() { 
    foo(STATE_A | STATE_B | STATE_C); 
} 
+8

Thậm chí tốt hơn, sử dụng 'enum STATE {STATE_A = 1 << 0, STATE_B = 1 << 1, STATE_C = 1 << 2};' - Tôi thấy rõ ràng hơn nhiều. – DevSolar

+3

Họ sẽ không được tiểu bang bằng cách này. Hoa có nghĩa là độc quyền. Chúng có nhiều khả năng là cờ (nơi các cờ riêng biệt độc lập với nhau). – paxdiablo

+0

cảm ơn, tôi đã làm nó giống như các bạn đề nghị và nó hoạt động! – moka

2

Bạn phải chia "thẻ" có thể (không chồng chéo tất nhiên ... sử dụng sức mạnh của 2):

if (_a & One) { ... } 

Không thanh lịch thực sự làm những gì bạn muốn với tuyên bố 1 công tắc: chia sử dụng if báo cáo .

2

Bạn đang khấm khá hơn làm việc đó với một tập hợp các câu lệnh if ...

tức

if (_a & ONE) 
{ 
    // Do stuff. 
} 
if (_a & TWO) 
{ 
    // Do other stuff. 
} 

chỉnh sửa: Bạn cũng có thể làm điều đó trong một câu lệnh switch nhưng nó sẽ là một cơn ác mộng. Bạn cần một cái gì đó như thế này

switch(_a) 
{ 
case ONE: 
    // Handle ONE. 
    break; 

case TWO: 
    // Handle TWO. 
    break; 

case ONE | TWO: 
    // Handle ONE. 
    // Handle TWO. 
    break; 
}; 

Nó tương đối sane chỉ có 2 lựa chọn nhưng một khi bạn nhận được nhiều hơn nó bắt đầu khinh khí cầu. Nếu bạn có 32 tùy chọn, bạn sẽ có một tuyên bố chuyển đổi mà có thể sẽ không phù hợp trên bất kỳ máy nào. Tất cả trong giải pháp "if" sạch hơn và sane hơn nhiều :)

+0

cảm ơn, bạn nói đúng, tôi sử dụng nếu phát biểu ngay bây giờ và nó hoạt động như một sự quyến rũ! – moka

3

Đối số thường được kết hợp theo cách đó là cờ (giá trị với một bộ bit) với giá trị thập phân là 1, 2, 4, 8 Giả sử One và Two tuân thủ quy tắc này, bạn không thể sử dụng nút chuyển để kiểm tra cả hai. Công tắc chỉ theo một đường dẫn. Đối số kết hợp của bạn không bằng một hoặc hai, nhưng kết hợp chúng (1 | 2 == 3). Bạn có thể kiểm tra xem nếu một hoặc hai được thiết lập như thế này:

if (_a & One) 
{ 

} 
if (_a & Two) 
{ 

} 

Hãy nhớ rằng một enum tiêu chuẩn không có giá trị rõ ràng sẽ chỉ đếm lên, không sử dụng các bit tiếp theo. Nếu giá trị được xác định tiếp theo của bạn là Ba, nó sẽ có khả năng bằng 3 mà không phải là một giá trị của một bit, và sau đó sẽ hành động như thể bạn đã vượt qua cả hai cờ (One | Two) cho hàm. Bạn sẽ cần phải tự đặt giá trị của enum.

8

nhà khai thác Bitwise cư xử tốt chỉ với lũy thừa của 2:

0010 
| 0100 
------ 
    0110 // both bits are set 


    0110 
& 0100 
------ 
    0100 // nonzero, i.e. true: the flag is set 

Nếu bạn cố gắng làm điều tương tự với số lượng tùy ý, bạn sẽ nhận được bất ngờ kết quả:

0101 // 5 
| 1100 // 12 
------ 
    1101 // 13 

Có chứa các số có thể (tùy ý) làm cờ set: 0001 (1), 0100 (4), 0101 (5), 1000 (8), 1001 (9), 1100 (12), 1101 (13)

Vì vậy, thay vì đưa ra hai lựa chọn, bạn chỉ cần đưa ra sáu.

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