2009-12-09 5 views
6

मैं हाल ही में कुछ फ़ंक्शंस में आया हूं जहां आप इस तरह के कई enums पारित कर सकते हैं:bitwise या "|" का उपयोग कर एक फ़ंक्शन तर्क में C++ एकाधिक enums

myFunction(One | Two); 

चूंकि मुझे लगता है कि यह वास्तव में एक शानदार तरीका है जिसे मैंने स्वयं कुछ ऐसा करने की कोशिश की:

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

अब अगर मैं फ़ंक्शन को वन के साथ कॉल करने का प्रयास करता हूं दो, मैं चाहता हूं कि दोनों स्विच केस बुलाए जाएं। मैं बाइनरी ऑपरेटरों के साथ वास्तव में अच्छा नहीं हूं इसलिए मुझे नहीं पता कि क्या करना है। सभी विचारों का स्वागत है!

धन्यवाद!

+1

अपनी 'enum' परिभाषा पोस्ट करें .. क्या आपको उन्हें 2 की सभी शक्तियां याद रखना याद आया? – eduffy

+1

नोट _A को C++ कार्यान्वयन के लिए आरक्षित किया गया है, जब तक यह वर्ग सदस्य का नाम न हो। –

उत्तर

11
है कि आप की तरह enums करना है के लिए

तो जब आप की तरह कार्य करें:

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

यहां तक ​​कि बेहतर, 'enum STATE {STATE_A = 1 << 0, STATE_B = 1 << 1, STATE_C = 1 << 2}; '- मुझे यह और अधिक स्पष्ट लगता है। – DevSolar

+3

वे रास्ते से राज्य नहीं होंगे। राज्य अनन्य होने के लिए हैं। वे झंडे होने की अधिक संभावना रखते हैं (जहां व्यक्तिगत झंडे एक-दूसरे से स्वतंत्र होते हैं)। – paxdiablo

+0

धन्यवाद, मैंने आपके जैसा सुझाव दिया है और यह काम करता है! – moka

2

आप संभव "टोकन" विभाजित करना होगा (बेशक गैर-अतिव्यापी ... 2 की शक्ति का उपयोग): if बयानों का उपयोग कर विभाजन:

if (_a & One) { ... } 

नहीं सुरुचिपूर्ण वास्तव में क्या आप 1 स्विच बयान के साथ करना चाहते हैं ।

2

आप यानी

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

संपादित करता है, तो बयान ...

का एक सेट के साथ यह कर बेहतर होगा: आप इसे एक स्विच बयान में भी कर सकता है, लेकिन यह एक बुरा सपना हो सकता है। योड इस

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

case TWO: 
    // Handle TWO. 
    break; 

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

इसकी तरह कुछ केवल 2 विकल्प के लिए अपेक्षाकृत समझदार की जरूरत है लेकिन एक बार आप से है कि यह नियंत्रण से बाहर balloon शुरू होता है और अधिक मिलता है। यदि आपके पास 32-विकल्प हैं तो आपके पास एक स्विच स्टेटमेंट होगा जो किसी भी मशीन पर फिट होने की संभावना नहीं होगी। "अगर" समाधान में बहुत साफ और बहुत अधिक सनी है :)

+0

धन्यवाद, आप सही हैं, अगर मैं अब कथन का उपयोग करता हूं और यह एक आकर्षण की तरह काम करता है! – moka

3

आमतौर पर तर्क जो कि संयुक्त होते हैं वे झंडे होते हैं (एक बिट सेट के साथ एक मान) 1, 2, 4, 8 के दशमलव मान के साथ , आदि मानते हैं कि एक और दो इस नियम का पालन करते हैं, आप दोनों के लिए जांच करने के लिए स्विच का उपयोग नहीं कर सकते हैं। स्विच केवल एक पथ का पालन करें। आपका संयुक्त तर्क एक या दो के बराबर नहीं है, लेकिन उनमें से एक संयोजन (1 | 2 == 3)। आप एक या दो इस तरह सेट है, तो देखने के लिए जाँच कर सकते हैं:

if (_a & One) 
{ 

} 
if (_a & Two) 
{ 

} 

, याद रखें कि स्पष्ट मान के बिना एक मानक enum सिर्फ ऊपर की ओर गिनती होगी अगले बिट का उपयोग नहीं। यदि आपका अगला परिभाषित मान तीन है, तो यह 3 बराबर होगा जो एक बिट का मूल्य नहीं है, और फिर कार्य करेगा जैसे कि आपने फ़ंक्शन में दोनों झंडे (एक | दो) पारित किए थे। आपको अपने आप को enum के मान सेट करने की आवश्यकता होगी। वैध मामले या अगर बयान का चयन करने के

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

अर्थात enum तत्व मान 2 की शक्ति में होना चाहिए:

8

बिटवाइज़ ऑपरेटर्स केवल 2 की शक्तियों के साथ अच्छी तरह से व्यवहार करते हैं:

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


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

आप मनमाने ढंग से संख्या के साथ भी ऐसा ही करने की कोशिश करते हैं, तो आप अप्रत्याशित मिल जाएगा परिणाम:

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

जिसमें फ्लैग सेट के रूप में संभावित (मनमानी) संख्याएं शामिल हैं: 0001 (1), 0100 (4), 0101 (5), 1000 (8), 1001 (9), 1100 (12), 1101 (13)

तो बजाय दो विकल्प दे रही है, तो आप सिर्फ छह दे दी है।

संबंधित मुद्दे