2009-12-09 12 views
6

Son zamanlarda, bu gibi birden fazla enumatı geçirebileceğiniz bazı fonksiyonlara rastladım:C++ bitwise kullanılarak bir işlev argümanında çoklu enums veya "|"

myFunction(One | Two); 

Bunun gerçekten çok zarif bir yol olduğunu düşündüğümden beri kendim gibi bir şeyi uygulamaya çalıştım:

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

Fonksiyonu One ile çağırmaya çalışıyorum. İki, her iki anahtar davasının aranmasını istiyorum. İkili operatörlerle gerçekten iyi değilim, bu yüzden gerçekten ne yapacağımı bilmiyorum. Herhangi bir fikir harika olurdu!

Teşekkürler!

+1

"Enum" tanımınızı gönderin .. 2'nin tüm yetkilerini almayı hatırladınız mı? – eduffy

+1

Not Bir sınıf üyesinin adı olmadığı sürece _a, C++ uygulaması için ayrılmıştır. –

cevap

11

.

seversin Yani:

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

Daha da iyisi, 'enum STATE {STATE_A = 1 << 0, STATE_B = 1 << 1, STATE_C = 1 << 2} 'yi kullanın;' - Ben bunu çok daha açık buluyorum. – DevSolar

+3

Bu arada devlet olmazlar. Devletler münhasır olmak içindir. Bayraklar olma olasılığı daha yüksektir (bayrakların birbirinden bağımsız olduğu yerler). – paxdiablo

+0

teşekkürler, sizlerin önerdiği gibi yaptım ve işe yarıyor! – moka

2
Sen (2 gücünü kullanmak ... tabii olmayan üste binmesini) mümkün "belirteçleri" bölünmüş olmalıdır

: if ifadelerini kullanarak bölünmüş:

if (_a & One) { ... } 

gerçekten 1 switch ifadesi ile istediğinizi zarif yapmak değil .

2

Sen

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

düzenlemek yani eğer tablolar ...

bir dizi ile yapıyor daha iyi olur: Bir anahtar açıklamada bunu da olabilir ama bir kabus olurdu. Youd sadece 2 seçenekleri için nispeten aklı başında bu

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

case TWO: 
    // Handle TWO. 
    break; 

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

Its gibi bir şey gerekir ama bunu kontrol dışı balon başlar bundan daha fazla bir kez. 32 seçeneğiniz varsa, herhangi bir makineye sığması olası olmayan bir anahtar deyiminiz olur. Tüm "if" çözümünde çok daha temiz ve çok daha fazla aklı var :)

+0

teşekkürler, haklısınız, şimdi ifadeler kullanıyorum ve çekicilik gibi çalışır! – moka

3

Bu şekilde birleştirilen argümanlar genellikle 1, 2, 4, 8 ondalık değeri olan bayraklardır (tek bit kümesine sahip bir değer) vb. Bir ve İki'nin bu kuralı izlediğini varsayarak, her ikisini de kontrol etmek için bir anahtar kullanamazsınız. Anahtarlar sadece bir yolu takip eder. Birleşik argümanınız bir veya iki eşit değildir, ancak bunların bir kombinasyonu (1 | 2 == 3). Sen Bir veya iki böyle ayarlanmış olup olmadığını görmek için kontrol edebilirsiniz:

if (_a & One) 
{ 

} 
if (_a & Two) 
{ 

} 

sonraki bit kullanmayın, açık değerler olmadan standart bir enum sadece yukarı saymak unutmayın. Eğer bir sonraki tanımladığınız değer Üç ise, muhtemelen bir bitin değeri olmayan 3'e eşit olacaktır ve daha sonra her iki bayrağı da (Bir | İki) fonksiyona aktarmışsınız gibi davranacaktır. Enum'un değerlerini kendiniz ayarlamanız gerekir. Geçerli durum veya eğer deyimi seçmek için

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

yani enum öğe değeri 2'nin gücü olmalıdır: Eğer gibi Çeteleler yapmak zorunda Bunun için

8

Bit operatörleri sadece 2 güçlerle iyi davranmak: Eğer keyfi sayılar ile aynı şeyi denerseniz

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


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

, beklenmeyen alırsınız sonuçlar:

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

Olası (rasgele) sayıları, set bayrakları olarak içerir: 0001 (1), 0100 (4), (5) 0101, 1000 (8), 1001 (9), 1100 (12), (13)

Yani yerine 1101 iki seçenek sunuyoruz, sadece altı verdi.