2010-12-09 11 views
7

क्या सिनाटैक्स अजीबता का एक त्वरित/ऑनलाइन तरीका है जो आपको यह जांचने की अनुमति देता है कि एनम के पास निर्दिष्ट लोगों का मूल्य है या नहीं?enum मानों की एक श्रृंखला की जांच करने के लिए त्वरित तरीका

उदाहरण:

enum fruit_and_vegetables 
{ 
    apples, 
    pears, 
    tomatoes, 
    cucumbers 
} 

int main() 
{ 
    fruit_and_vegetables something = apples; 
    if(something = {apples, pears}) // <-- this here 
     cout << "something is fruit." << endl; 
    else 
     cout "something is a vegetable." << endl; 
    return 0; 
} 

धन्यवाद!

+2

टमाटर और खीरे * हैं * फल ;-p –

+0

SCOTUS के अनुसार नहीं: http://en.wikipedia.org/wiki/Tomato#Fruit_or_vegetable.3F –

+0

@Noah: 'टमाटर * हैं' और टमाटर नहीं है * ' – ruslik

उत्तर

4

आह, यह किया जा सकता है काफी आसानी से...

template <typename T> 
pair<T, fruit_and_vegetables> operator||(T t, fruit_and_vegetables v) { 
    return make_pair(t, v); 
} 

template <typename T> 
bool operator==(fruit_and vegetables lhs, pair<T, fruit_and_vegetables> rhs) { 
    return lhs == rhs.second || lhs == rhs.first; 
} 

यह तो की तरह इस्तेमाल किया जा सकता है:

if (something == (apple || pear || orange)) eat_the_yummy_fruit(something); 
else feed_to_rabbit(something) 

लेकिन अगर आप (apple || (pear || orange)) कर काम नहीं करेगा। इसे आसानी से ठीक किया जा सकता है लेकिन मैं कोड को सरल रखना चाहता था। मेरा मानना ​​है कि यह अब तक का एकमात्र उत्तर है जो वास्तव में बड़े enums के लिए scales ...

+0

क्या बड़ी श्रेणियां भी काम करने का कोई तरीका होगा? यह पूरी तरह से ब्याज से बाहर होगा, आपका समाधान मुझे वह करने की अनुमति देता है जो मैं पूरी तरह से चाहता हूं! धन्यवाद। – rubenvb

4

if (something < tomatoes)...

+1

आह हां, '"मैंने इसके बारे में क्यों नहीं सोचा" (सी) '... लेकिन क्या होगा यदि enum के मध्यवर्ती मूल्य हैं और मेरा उदाहरण अधिक जटिल/अपरिवर्तित हो जाता है? टमाटर का दावा करने के लिए – rubenvb

5

ऐसा नहीं है कि मैं के बारे में पता है, लेकिन आप क्या कर सकते असाइन मूल्यों enum सदस्यों को 2^i है। उदाहरण के लिए:

enum fruit_and_vegetables 
{ 
    apples = (1<<0), 
    pears  = (1<<1), 
    tomatoes = (1<<2), 
    cucumbers = (1<<3) 
    // ... 
} 

तो फिर तुम

if (something & (apples | pears | tomatoes)) 
    std::cout << "is tasty" << std::endl; 

बेशक से सलाह ले सकते, यह एक उचित आकार के साथ enums लिए सीमित है (मुझे लगता है कि आप अप करने के लिए 32 तत्वों हो सकता है)।

संपादित

आप 32 से अधिक (64) मान हैं, तो आप इस से अधिक रचनात्मक होना है। कई चेकों करने से, आप अभी भी यथोचित जल्दी हो सकता है:

enum fruit_and_vegetables { 
    apples = 1, //! 
    pears, 
    tomatoes, 
    cucumbers, 
    // ... 
    grapes 
} 
#define FRUIT_AND_VEGETABLES 120 

if ( (1<<something)  & ((1<<apples) | (1<<pears) | (1<<tomatoes)) 
    || (1<<(something-32) & ((1<<(apples-32)) | (1<<(pears-32)) | (1<<(tomatoes-32)))) 
    || ...) { 
    std::cout << "my keyboard is broken, but tastes good" << std::endl; 
} 

लेकिन वह वास्तव में एक महान समाधान नहीं है। यदि आपके पास बड़ी संख्या में enums हैं और उन्हें कई वर्गों में विभाजित किया जा सकता है, तो मैं Noah Roberts' answer के साथ जाऊंगा।

+1

-1 स्वादिष्ट हैं! जे/के हालांकि मैं कहूंगा कि जब तक आप इस तरह के व्यवहार को अपने enum से करना चाहते हैं, तो एक enum वास्तव में आपके इच्छित व्यवहार के लिए एक उपयुक्त निर्माण नहीं है। –

+2

आपको मजाक करनी होगी! टमाटर **** भयानक हैं! – bitmask

+2

@bitmask: अगर enum में 70 सदस्य हैं तो क्या होगा? यह leftshift दृष्टिकोण काम नहीं करेगा! – Nawaz

1

एक और तरीका नहीं है, कि @bitmask का जवाब लागू होता है:

मान लीजिए मानदंड है कि आप जांच कर सकता है की एक निश्चित संख्या नहीं है।

enum fruit_and_vegetables { 
    apples = 0, 
    pears, 
    tomatoes, 
    cucumbers 
} 

enum qualifs { 
    is_fruit = 1, 
    is_sweet = 1<<1, 
    is_round = 1<<2, 
    is_tasty = 1<<3 
} 

const qualifs qualifs_LUT[] = { // can be generated 
    is_fruit | is_sweet | is_round, // apple 
    ... 
}; 

ताकि एक विशिष्ट क्वालीफायर इच्छा के लिए जाँच हो गया

if (qualifs_LUT[tomato] & is_tasty) 
: तो, बजाय fruit_and_vegetables enum के मूल्यों के लिए bitmask का उपयोग कर के, आप अतिरिक्त LUT उपयोग कर सकते हैं (यह है कि आप शब्द के आकार को सीमित कर देंगी)

संपादित करें: और एक और दिलचस्प तरीका। @bitmask: विधि (दोबारा) पर विचार करें। यह 2 की शक्तियों पर निर्भर करता है लेकिन प्राइम्स के बारे में कैसे? वे और अधिक धीरे धीरे बढ़ता है, तो enum मूल्यों के लिए रूढ़ अंक बताए द्वारा, आप और अधिक मूल्यों squize सकता है, कि उत्पाद मानते हुए नहीं होगा अतिप्रवाह:

enum fruit_and_vegetables { 
    apples = 2, 
    pears = 3, 
    tomatoes = 5, 
    cucumbers = 7 
} 

if ((apples * pears * tomatoes) % tomatoes == 0) 
    printf("it's tasty!"); 

यह एक नियंत्रण सेट में आइटम्स की संख्या को सीमित कर रहा है।

+0

इसे प्यार करें! (लेकिन आपको शायद लूट 'const' बनाना चाहिए) – bitmask

+0

@bitmask: ठीक है, यह सिर्फ एक कार्यान्वयन विस्तार है :) – ruslik

+0

मुझे पता है, लेकिन मुझे 15 अक्षर भरना पड़ा :) – bitmask

1

आप जो आप वाक्य रचना जो आप चाहते हैं को प्राप्त करने में मदद मिलेगी सहायक टेम्पलेट लिख सकते हैं:

enum fruit_and_vegetables 
{ 
    nothing, 
    apples, 
    pears, 
    tomatoes, 
    cucumbers 
}; 

// helper template 
typedef fruit_and_vegetables fav; 
template<fav v1 = nothing, fav v2 = nothing, fav v3 = nothing, fav v4 = nothing, 
    fav v5 = nothing, fav v6 = nothing, fav v7 = nothing, fav v8 = nothing> 
bool check_equal(fruit_and_vegetables value) 
{ 
    return (value == v1 || value == v2 || value == v3 || value == v4 || 
      value == v5 || value == v6 || value == v7 || value == v8); 
} 

// usage 
int main() 
{ 
    fruit_and_vegetables something = apples; 
    if(check_equal<apples, pears>(something)) 
     std::cout << "something is fruit." << std::endl; 
    else 
     std::cout << "something is a vegetable." << std::endl; 

    return 0; 
} 
+0

यह प्रत्येक मूल्य को हाथ से जांचने जैसा ही है। ओपी ने स्पष्ट से तेज विधि की मांग की। – ruslik

+1

ओपी ने सरल वाक्यविन्यास के बारे में पूछा: "synatx अजीबता का ऑनलाइन तरीका"। –

1

बड़ा संभाल करने के लिए, उपज का अवर्गीकृत सेट:

enum fruit_and_vegetables 
{ 
    apples, 
    pears, 
    tomatoes, 
    cucumbers, 
    MAX_VALUE 
}; 

vector<bool> arguablyVegetables(MAX_VALUE, false); 
arguablyVegetables[tomatoes] = true; 
arguablyVegetables[cucumbers] = true; 

cout << arguablyVegetables[apples] << endl; 
1

का उपयोग fruit_and_vegetables लॉजिकल-या-आईएनजी के लिए क्यों नहीं करते?) तराजू अच्छी तरह से करने के लिए; अगर आप == भार के, के साथ ही तर्क और परिणाम प्रकार से पहले से पहले ऑपरेटर || और ऑपरेटर constexpr शब्दों में कहें, तो संकलक संकलन समय पर अपने कोड (कोई क्रम भूमि के ऊपर) यदि संभव हो तो मूल्यांकन करेंगे बड़ा a || b || c || c enum श्रेणियां और आप मूल्यों को ब्रैकेट में डाल सकते हैं जैसा आप चाहते हैं।

#include <set> 
using std::set; 

enum fruit_and_vegetables 
{ 
    apples, 
    pears, 
    tomatoes, 
    cucumbers 
}; 

set<fruit_and_vegetables> operator||(fruit_and_vegetables left, fruit_and_vegetables right) { 
    set<fruit_and_vegetables> set; 
    set.insert(left); 
    set.insert(right); 
    return set; 
} 

set<fruit_and_vegetables> operator||(set<fruit_and_vegetables> left, fruit_and_vegetables right) { 
    left.insert(right); 
    return left; 
} 

set<fruit_and_vegetables> operator||(fruit_and_vegetables left, set<fruit_and_vegetables> right) { 
    right.insert(left); 
    return right; 
} 

bool operator!=(fruit_and_vegetables lhs, set<fruit_and_vegetables> rhs) { 
    return (rhs.find(lhs) == rhs.end()); 
} 

bool operator==(fruit_and_vegetables lhs, set<fruit_and_vegetables> rhs) { 
    return !(lhs != rhs); 
} 

int main() { 

fruit_and_vegetables fav = apples; 
if (fav == (apples || (pears || tomatoes))) cout << "match apples\n"; 
fav = cucumbers; 
if (fav == ((apples || pears) || tomatoes)) cout << "Error! matched ghost cucumbers\n"; 
if (fav != apples) cout << "correct no match apples\n"; 
if (fav == cucumbers) cout << "default operator==(FaV, FaV) match\n"; 
if (fav == (pears || apples)) cout << "yummi\n"; 

return 0; 
} 
संबंधित मुद्दे