मैं एक enum पर फिर से कैसे कर सकते हैं?

मैंने अभी देखा है कि आप मानक गणित ऑपरेटरों का उपयोग एनम पर ++ या + = जैसे नहीं कर सकते हैं

तो सी ++ एनम में सभी मूल्यों के माध्यम से पुन: प्रयास करने का सबसे अच्छा तरीका क्या है?

0
लिंक्ड वस्तुओं में कुछ दिलचस्प प्रतिक्रियाएं होती हैं।
जोड़ा लेखक Tony, स्रोत
ये उत्तर उस समस्या को कवर नहीं करते हैं जो int पर्याप्त नहीं हो सकता है! (<कोड> [सी ++ 03: 7.2/5] )
जोड़ा लेखक Lightness Races in Orbit, स्रोत
जोड़ा लेखक Jarod42, स्रोत
यदि संकलन समय ऑपरेटर था, तो आकार के काम के समान, जो end के मानों से युक्त std :: startizer_list शब्दशः उत्सर्जित कर सकता है, हमारे पास एक समाधान होगा और इसमें कोई रनटाइम ओवरहेड शामिल नहीं होगा।
जोड़ा लेखक jbruni, स्रोत
दिलचस्प बात यह है कि आप enums पर operator ++ को परिभाषित कर सकते हैं; हालांकि, आप के लिए (Enum_E e = (Enum_E) 0; e कर सकते हैं। ध्यान दें कि आपको 0 को Enum_E पर डालना होगा क्योंकि C ++ enums पर असाइनमेंट ऑपरेटर को रोकता है।
जोड़ा लेखक weberc2, स्रोत

17 उत्तर

आप एक enum के साथ नहीं कर सकते हैं। शायद एक enum आपकी स्थिति के लिए सबसे अच्छा फिट नहीं है।

एक आम सम्मेलन अंतिम एनम मान को MAX की तरह कुछ नाम देना है और एक int का उपयोग करके लूप को नियंत्रित करने के लिए इसका उपयोग करना है।

0
जोड़ा

कई दृष्टिकोणों में से एक: जब enum बस पर्याप्त नहीं है : सी ++ के लिए गणना कक्षाएं

और, यदि आप कुछ और encapsulated चाहते हैं, तो यह दृष्टिकोण आज़माएं जेम्स कानज़ से।

0
जोड़ा
मैं आमतौर पर पुराने उत्तरों पर टिप्पणी करने के लिए अनिच्छुक हूं (मुझे याद नहीं है कि मैंने 2008 में क्या लिखा था!), हालांकि डॉ डॉब्स लेख बल्कि खराब है। विचार अच्छा है, लेकिन उदाहरण कार्यान्वयन काफी भयानक है। उदाहरण: enum_11 (11) , भगवान: एक्स
जोड़ा लेखक Matthieu M., स्रोत
यह फिर से काम कर रहा है, इसलिए मुझे लगता है कि सर्वर पहले नीचे था।
जोड़ा लेखक GOTO 0, स्रोत
उपयोगी लिंक सहित धन्यवाद!
जोड़ा लेखक jwfearn, स्रोत
खुशी हुई, @jwfearn!
जोड़ा लेखक Don Wakefield, स्रोत
MatthieuM पर टिप्पणी। एक लंबे समय से टिप्पणी है। मैंने कुछ हफ्ते पहले @ डॉनवेकफील्ड के डॉ। डॉब के लिंक को स्वतंत्र रूप से पाया था और इसे समझने के लिए घंटों तक कोशिश की थी। मैं सी ++ के लिए नया हूं और गॉर्डियन गांठ को खोल नहीं सकता। अगर कोई इसे आधुनिक, पठनीय और डी-ओबस्कसेटेड तरीके से फिर से कार्यान्वित कर सकता है तो यह वास्तव में सहायक होगा। मैं ऐसा करने में असमर्थ था।
जोड़ा लेखक Matthew James Briggs, स्रोत
पहला लिंक अब टूटा हुआ है, यहां ले जाया गया है: drdobbs.com/जब-enum-बस-नहीं है-काफी-गणन-सी/1844039 और जेडडब्ल्यूएनजे, 55
जोड़ा लेखक merosss, स्रोत

यदि आपका enum 0 से शुरू होता है और वृद्धि हमेशा 1 होती है।

enum enumType 
{ 
    A = 0,
    B,
    C,
    enumTypeEnd
};

for(int i=0; i

यदि नहीं, तो मुझे लगता है कि केवल कुछ ऐसा क्यों बनाना है

vector vEnums;

आइटम जोड़ें, और सामान्य iterators का उपयोग करें ....

0
जोड़ा

ऐसा कुछ जो अन्य उत्तरों में शामिल नहीं किया गया है = यदि आप दृढ़ता से टाइप किए गए C ++ 11 enums का उपयोग कर रहे हैं, तो आप उन पर ++ या + int का उपयोग नहीं कर सकते हैं। उस स्थिति में, एक मेसियर समाधान का एक बिट आवश्यक है:

enum class myenumtype {
  MYENUM_FIRST,
  MYENUM_OTHER,
  MYENUM_LAST
}

for(myenumtype myenum = myenumtype::MYENUM_FIRST;
    myenum != myenumtype::MYENUM_LAST;
    myenum = static_cast(static_cast(myenum) + 1)) {

  do_whatever(myenum)

}
0
जोड़ा
... लेकिन सी ++ 11 उस श्रेणी के आधार पर प्रस्तुत करता है जो अन्य उत्तरों में दिखाया गया है। :-)
जोड़ा लेखक sage, स्रोत
#include 
#include 

namespace MyEnum
{
  enum Type
  {
    a = 100,
    b = 220,
    c = -1
  };

  static const Type All[] = { a, b, c };
}

void fun( const MyEnum::Type e )
{
  std::cout << e << std::endl;
}

int main()
{
 //all
  for ( const auto e : MyEnum::All )
    fun( e );

 //some
  for ( const auto e : { MyEnum::a, MyEnum::b } )
    fun( e );

 //all
  std::for_each( std::begin( MyEnum::All ), std::end( MyEnum::All ), fun );

  return 0;
}
0
जोड़ा
धन्यवाद! ध्यान दें कि यदि आप फ़ाइलों/कक्षाओं को पार कर रहे हैं और यदि एमएस संगतता आपको हेडर-घोषित गैर-पूर्णांक स्थिरांक के साथ समस्याएं दे रही है, तो यह मेरे कंपाइलर के नीचे हेडर में प्रकार को आकार में स्पष्ट रूप से रखने में मदद करता है: स्थिर कॉन्स प्रकार सभी [3]; और फिर मैं स्रोत में आरंभ करने में सक्षम हूं: const MyEnum :: MyEnum टाइप करें :: सभी [3] = {ए, बी, सी}; इससे पहले ऐसा करने से, मैं अपमानजनक <कोड> श्रेणी-दर-श्रेणी में त्रुटि प्राप्त कर रहा था ... त्रुटियां (क्योंकि सरणी का अज्ञात आकार था)। सं
सरणी संस्करण कॉपी पेस्ट के बहुत दोस्ताना है। इसके अलावा सबसे संतोषजनक उत्तर, "नहीं" या "केवल अनुक्रमिक के लिए"। शायद मैक्रो दोस्ताना भी।
जोड़ा लेखक Paulo Neves, स्रोत

आप अपने गणित प्रकार के लिए वृद्धि/कमी ऑपरेटर को भी अधिभारित कर सकते हैं।

0
जोड़ा
आप सी या सी ++ समेकित प्रकारों पर किसी भी ऑपरेटरों को अधिभारित नहीं कर सकते हैं। जब तक आप एक संरचना/वर्ग नहीं बनाते थे जो मूल्यों की गणना को अनुकरण करता था।
जोड़ा लेखक Trevor Hickey, स्रोत
सी ++ enums पर ऑपरेटरों ऑपरेटिंग की अनुमति देता है। Enums"> stackoverflow.com/questions/2571456/… के लिए जोड़ा लेखक Arch D. Robison, स्रोत

सी ++ में आत्मनिरीक्षण नहीं है, इसलिए आप इस तरह की चीज को रन-टाइम पर निर्धारित नहीं कर सकते हैं।

0
जोड़ा
मैं दो टिप्पणियों में फिर से क्रैक करूंगा: 1) मैं डाउनवोट नहीं करता क्योंकि मुझे लगता है कि डाउनवोट प्राप्त करने से साइट भागीदारी में कमी आती है, मुझे लगता है कि प्रतिकूल 2) मैं अभी भी समझ नहीं पा रहा हूं कि आप क्या कहने की कोशिश कर रहे हैं लेकिन ऐसा लगता है आप कुछ समझते हैं जो मैं नहीं करता हूं, इस मामले में मैं आपको एक संक्षिप्त जवाब हटाने के बजाय विस्तृत करना चाहता हूं।
जोड़ा लेखक Jonathan Mee, स्रोत
मैं 2 चीजें कहने की कोशिश कर रहा हूं: 1) कई अन्य उत्तरों के बाद सी ++ इसे पूरा कर सकता है, इसलिए यदि आप यह कहने जा रहे हैं कि यह नहीं हो सकता है, तो एक लिंक या आगे स्पष्टीकरण की आवश्यकता है। 2) इसके वर्तमान रूप में यह एक टिप्पणी है, निश्चित रूप से एक जवाब नहीं है।
जोड़ा लेखक Jonathan Mee, स्रोत
क्या आप मुझे समझा सकते हैं कि एक enum पर फिर से करने के लिए "आत्मनिरीक्षण" की आवश्यकता क्यों होगी?
जोड़ा लेखक Jonathan Mee, स्रोत
शायद शब्द प्रतिबिंब है?
जोड़ा लेखक David Kemp, स्रोत
तब मेरा जवाब डाउनवोट करें - मुझे लगता है कि आपको इसे उचित ठहराने से अधिक है
जोड़ा लेखक David Kemp, स्रोत
सी ++ वास्तव में प्रकार आत्मनिरीक्षण का समर्थन करता है। टाइपिड और गतिशील_कास्ट देखें
जोड़ा लेखक user3063349, स्रोत

इस प्रकार का सामान्य तरीका है:

enum Foo {
  One,
  Two,
  Three,
  Last
};

for ( int fooInt = One; fooInt != Last; fooInt++ )
{
   Foo foo = static_cast(fooInt);
  //...
}

बेशक, अगर enum मान निर्दिष्ट हैं तो यह टूट जाता है:

enum Foo {
  One = 1,
  Two = 9,
  Three = 4,
  Last
};

यह दिखाता है कि एक enum वास्तव में फिर से शुरू करने के लिए मतलब नहीं है। एक enum से निपटने के लिए सामान्य तरीका एक स्विच स्टेटमेंट में इसका उपयोग करना है।

switch ( foo )
{
    case One:
       //..
        break;
    case Two: //intentional fall-through
    case Three:
       //..
        break;
    case Four:
       //..
        break;
     default:
        assert( ! "Invalid Foo enum value" );
        break;
}

यदि आप वास्तव में गणना करना चाहते हैं, तो वेक्टर में enum मानों को भरें और उस पर पुनरावृत्त करें। यह निश्चित रूप से निर्दिष्ट enum मानों के साथ भी सौदा करेगा।

0
जोड़ा
सिवाय इसके कि आपने वास्तव में स्मृति को आवंटित किया है जब एक enum, बशर्ते यह शून्य-अनुक्रमित और कड़ाई से निरंतर है, स्मृति को आवंटित किए बिना वह कार्य कर सकता है।
जोड़ा लेखक DevNull, स्रोत
इसके अलावा आप लूप में अंतिम छोड़ रहे हैं। <= अंतिम होना चाहिए
जोड़ा लेखक Tony, स्रोत
ध्यान दें कि इस enum परिभाषा के लिए अद्यतनों के लिए सुरक्षित होने के लिए किसी को एक मूल्य UNKNOWN = 0 परिभाषित करना चाहिए। इसके अतिरिक्त, मैं enum मानों पर स्विच करते समय default केस को छोड़ने का सुझाव दूंगा क्योंकि यह उन मामलों को छुपा सकता है जहां रनटाइम तक मानों को संभालना भूल गया था। इसके बजाय किसी को सभी मूल्यों को हार्डकोड करना चाहिए और असंगतताओं का पता लगाने के लिए UNKNOWN फ़ील्ड का उपयोग करना चाहिए।
जोड़ा लेखक Benjamin Bannier, स्रोत
@tsusanka यह वास्तव में एक एसटीएल कंटेनर पर पुनरावृत्ति के रूप में एक ही तर्क पर काम करता है। जैसे std :: end() एक "बाद के अंत" इटेटरेटर देता है ताकि आप i या का उपयोग कर सकें ! = std :: end (जो भी हो) , enum के अंत में एक डमी मान जोड़ने के लिए उपयोगी हो सकता है ताकि आप i का उपयोग कर सकें । इसी प्रकार, यदि एक enum का उपयोग पुनरावृत्ति के लिए किया जाना है, तो यह एक डमी <कोड> पहला तत्व जोड़ने के लिए भी उपयोगी हो सकता है, जिसका अंतर्निहित मान वास्तविक पहले तत्व के मान के समान होता है। इस
जोड़ा लेखक Justin Time, स्रोत
आप मैक्रोज़ का भी उपयोग कर सकते हैं लेकिन इसका मतलब है कि आपको मैक्रो के माध्यम से अपने enum को परिभाषित करने की आवश्यकता है। इस तरह आप वास्तव में कास्टिंग से बचते हैं और वेक्टर का उपयोग करने की ज़रूरत नहीं है!
जोड़ा लेखक ChaoSXDemon, स्रोत
ध्यान दें कि, उदाहरण के पहले भाग में, यदि आप 'i' को फू एनम के रूप में उपयोग करना चाहते हैं और एक int नहीं, तो आपको इसे स्थिर करने की आवश्यकता होगी: static_cast (i)
जोड़ा लेखक Clayton, स्रोत
@ टोनी लास्ट छोड़ने के लिए है। यदि आप बाद में अधिक enums जोड़ना चाहते हैं, तो उन्हें अंतिम से पहले जोड़ें ... पहले उदाहरण में लूप अभी भी काम करेगा। एक "नकली" अंतिम enum का उपयोग करके, आपको हर बार जब आप एक नया enum जोड़ना चाहते हैं तो अंतिम "वास्तविक" enum के लिए लूप के लिए अपनी समाप्ति स्थिति को अपडेट करने की आवश्यकता नहीं है।
जोड़ा लेखक timidpueo, स्रोत
जवाब में टोनी की टिप्पणी पेस्ट करना बहुत ही अच्छा होगा। मैं वास्तव में उसमें उलझन में था।
जोड़ा लेखक tsusanka, स्रोत

आप निम्न मैक्रो को आजमा सकते हैं और परिभाषित कर सकते हैं:

#define for_range(_type, _param, _A1, _B1) for (bool _ok = true; _ok;)\
for (_type _start = _A1, _finish = _B1; _ok;)\
    for (int _step = 2*(((int)_finish)>(int)_start)-1;_ok;)\
         for (_type _param = _start; _ok ; \
 (_param != _finish ? \
           _param = static_cast<_type>(((int)_param)+_step) : _ok = false))

अब आप इसका इस्तेमाल कर सकते हैं:

enum Count { zero, one, two, three }; 

    for_range (Count, c, zero, three)
    {
        cout << "forward: " << c << endl;
    }

इसका उपयोग बिना हस्ताक्षर किए, पूर्णांक, enums और chars के माध्यम से पीछे और आगे पुनरावृत्त करने के लिए किया जा सकता है:

for_range (unsigned, i, 10,0)
{
    cout << "backwards i: " << i << endl;
}


for_range (char, c, 'z','a')
{
    cout << c << endl;
}

इसकी अजीब परिभाषा के बावजूद इसे बहुत अच्छी तरह से अनुकूलित किया गया है। मैंने वीसी ++ में डिस्सेबलर को देखा। कोड बेहद कुशल है। मत छोड़ो लेकिन बयान के लिए तीन: संकलक अनुकूलन के बाद केवल एक पाश का उत्पादन करेगा! आप संलग्न लूप को भी परिभाषित कर सकते हैं:

unsigned p[4][5];

for_range (Count, i, zero,three)
    for_range(unsigned int, j, 4, 0)
    {   
        p[i][j] = static_cast(i)+j;
    }

आप निश्चित रूप से अंतराल प्रकार के माध्यम से अंतराल के साथ पुनरावृत्त नहीं कर सकते हैं।

0
जोड़ा
यह एक अद्भुत हैक है! हालांकि यह सी ++ की तुलना में सी के लिए अधिक उपयुक्त है, लेकिन कोई भी कह सकता है।
जोड़ा लेखक einpoklum, स्रोत
_A1 एक अनुमत नाम नहीं है, यह निम्नलिखित पूंजी पत्र के साथ एक अग्रणी अंडरस्कोर है।
जोड़ा लेखक Martin Ueding, स्रोत

इन समाधानों को बहुत जटिल बनाते हैं, मुझे ऐसा लगता है:

enum NodePosition { Primary = 0, Secondary = 1, Tertiary = 2, Quaternary = 3};

const NodePosition NodePositionVector[] = { Primary, Secondary, Tertiary, Quaternary };

for (NodePosition pos : NodePositionVector) {
...
}
0
जोड़ा
क्या सी ++ के लिए अनुमति देता है (नोडपोजिशन पॉज़: नोडपॉजिशन वेक्टर) वाक्यविन्यास? जहां तक ​​मुझे पता है कि यह जावा सिंटैक्स है, और आपको कुछ समान करने के लिए सी ++ में इटरेटर की आवश्यकता होगी।
जोड़ा लेखक thegreatjedi, स्रोत
@thegreatjedi सी ++ 11 के बाद से आप यहां तक ​​कि सिंपियर कर सकते हैं: (ऑटो पॉज़: नोडपोशन वेक्टर) {..}
जोड़ा लेखक Enzojz, स्रोत
मुझे उम्मीद है कि यह इसलिए था क्योंकि प्रविष्टियों को दो स्थानों पर बनाए रखा जाना चाहिए।
जोड़ा लेखक Ant, स्रोत
मुझे नहीं पता कि यह क्यों कम हो गया था। यह एक उचित समाधान है।
जोड़ा लेखक Paul Brannan, स्रोत

सी ++ 11 के साथ, वास्तव में एक विकल्प है: एक साधारण templatized कस्टम इटरेटर लिखना।

मान लें कि आपका enum है

enum class foo {
  one,
  two,
  three
};

यह जेनेरिक कोड चाल करेगा, काफी कुशलता से - एक सामान्य हेडर में रखें, यह आपको किसी भी enum के लिए सेवा देगा जो आपको फिर से शुरू करने की आवश्यकता हो सकती है:

#include 
template < typename C, C beginVal, C endVal>
class Iterator {
  typedef typename std::underlying_type::type val_t;
  int val;
public:
  Iterator(const C & f) : val(static_cast(f)) {}
  Iterator() : val(static_cast(beginVal)) {}
  Iterator operator++() {
    ++val;
    return *this;
  }
  C operator*() { return static_cast(val); }
  Iterator begin() { return *this; } //default ctor is good
  Iterator end() {
      static const Iterator endIter=++Iterator(endVal);//cache it
      return endIter;
  }
  bool operator!=(const Iterator& i) { return val != i.val; }
};

आपको इसे विशेषज्ञ बनाना होगा

typedef Iterator fooIterator;

और फिर आप रेंज के लिए उपयोग कर सकते हैं

for (foo i : fooIterator() ) { //notice the parenteses!
   do_stuff(i);
}

धारणा है कि आपके पास अपने enum में अंतराल नहीं है अभी भी सच है; एनम मूल्य को स्टोर करने के लिए वास्तव में आवश्यक बिट्स की संख्या पर कोई धारणा नहीं है (std :: underlying_type के लिए धन्यवाद)

0
जोड़ा
@ केलीस्ट्रैंड: आपको मिल गया! जो अब पूरी तरह से समझ में आता है। क्या कोड अपडेट किया जाना चाहिए? आपकी व्याख्या के लिए सभी को धन्यवाद।
जोड़ा लेखक lepe, स्रोत
@AndrewLazarus: क्षमा करें, मेरे बुरे ... मैंने उन मूल्यों को इसे foo के लिए अलग करने के लिए सेट किया है, लेकिन इसके बारे में मुझे चिंता नहीं है। कृपया मेरी पिछली टिप्पणी से बदलें और enum को सेट करें: enum color {green, black, white, blue, red} । मुझे फ्रांसेस्को द्वारा प्रस्तावित कोड का उपयोग करने की आवश्यकता कैसे है, इसलिए मैं अपने कोड को संशोधित किए बिना foo या color को पुन: सक्रिय कर सकता हूं? यदि संभव हो, तो मैं एक उदाहरण कोड देखना चाहता हूं।
जोड़ा लेखक lepe, स्रोत
@AndrewLazarus, @ केली: तो अगर मेरे पास एक और enum है: enum color {green = 20, white = 30, red = 40} मैं foo को बदले बिना उपरोक्त कोड का उपयोग कैसे कर सकता हूं ऑपरेटर *() {... भाग? क्या कोई उदाहरण कोड के साथ समझा सकता है? (क्षमा करें मेरे सी ++ कौशल अभी तक उन्नत नहीं हैं)।
जोड़ा लेखक lepe, स्रोत
कृपया ध्यान दें कि "जेनेरिक कोड" "foo" से जुड़ा हुआ है (मध्य के बारे में कोड देखें), इसलिए आप वास्तव में इसे अन्य enum परिभाषाओं के साथ उपयोग नहीं कर सकते हैं।
जोड़ा लेखक lepe, स्रोत
और "अधिक सामान्य" से मेरा मतलब है कि यह निर्धारित करने के लिए कि यह विशेष int-value मान्य enum मान हैं या नहीं, यह निर्धारित करने के लिए IsEnumValid (जिसे आसानी से नामस्थान में स्थानांतरित किया जा सकता है) नामक एक अधिभारित वैश्विक फ़ंक्शन पर निर्भर करता है, "छोड़ने" समस्या हल करता है। वैधता-जांच कार्य को टेम्पलेट पैरामीटर में से एक बनाना एक विकल्प होगा। एक और को पुनरावृत्ति के लिए स्थैतिक सरणी के अस्तित्व की आवश्यकता होगी, जैसा कि stackoverflow.com/a/26910769/1858225 में है
जोड़ा लेखक Kyle Strand, स्रोत
मैंने वास्तव में यहां कुछ और सामान्य संस्करण बनाया है: github.com/ BatmanAoD/PublicPaste/ब्लॉब/मास्टर/GenericCppCode/& जेडडब्ल्यूएनजे; & hellip;
जोड़ा लेखक Kyle Strand, स्रोत
@lepe यह कहने जैसा है कि std :: vector सामान्य नहीं है क्योंकि std :: vector foo से जुड़ा हुआ है।
जोड़ा लेखक Kyle Strand, स्रोत
ओह, मुझे समस्या दिखाई दे रही है - foo ऑपरेटर *() {... सी ऑपरेटर *() {... होना चाहिए।
जोड़ा लेखक Kyle Strand, स्रोत
@lepe कुछ हद तक सामान्य (हालांकि सीमित) तरीके से "skips" समस्या को हल करने के लिए, नीचे मेरा उत्तर देखें। साथ ही, ध्यान दें कि आप केवल एक व्यक्ति को टिप्पणी में टैग कर सकते हैं (इसलिए जब आपने मुझे टैग करने का प्रयास किया तो मुझे अधिसूचित नहीं किया गया)।
जोड़ा लेखक Kyle Strand, स्रोत
@lepe प्रत्येक enum के पास स्वयं (टेम्पलेट-विशिष्ट) इटरेटर प्रकार होगा, जैसे कि आपको विभिन्न प्रकार की ऑब्जेक्ट्स रखने के लिए एक अलग std :: vector प्रकार की आवश्यकता होगी। यह पिछले टिप्पणी के रूप में टेम्पलेट विशेषज्ञता के माध्यम से पूरा किया जाता है। बिंदु यह है कि आपको प्रत्येक अद्वितीय enum प्रकार के लिए Iterator टेम्पलेट को फिर से परिभाषित करने की आवश्यकता नहीं है, जैसे कि आपको std :: vector टेम्पलेट को फिर से परिभाषित करने की आवश्यकता नहीं है प्रत्येक वस्तु प्रकार; आप बस इसे विशेषज्ञ करते हैं, जिसे एक-पंक्ति typedef के स
जोड़ा लेखक Kyle Strand, स्रोत
typedef Iterator colorIterator; सुनिश्चित करें कि आप समझते हैं कि टेम्पलेट इंस्टॉलेशन कैसे काम करते हैं।
जोड़ा लेखक Andrew Lazarus, स्रोत
@ स्लीप छोड़ने के कारण, आपको ++ वैल के बदले वैल + = 10 का उपयोग करने के लिए ऑपरेटर ++ का विशेषज्ञ होना होगा।
जोड़ा लेखक Andrew Lazarus, स्रोत
@ स्लीप? आप बस एक अलग enum के लिए एक अलग typedef बनाते हैं।
जोड़ा लेखक Andrew Lazarus, स्रोत

एमएस कंपाइलर्स के लिए:

#define inc_enum(i) ((decltype(i)) ((int)i + 1))

enum enumtype { one, two, three, count};
for(enumtype i = one; i < count; i = inc_enum(i))
{ 
    dostuff(i); 
}

नोट: यह सरल templatized कस्टम इटरेटर उत्तर से बहुत कम कोड है।

आप इसे declofpe के बजाय typeof का उपयोग कर जीसीसी के साथ काम करने के लिए प्राप्त कर सकते हैं, लेकिन मेरे पास संकलन सुनिश्चित करने के लिए इस समय संकलक आसान नहीं है।

0
जोड़ा

यदि आप अंतिम COUNT आइटम के साथ प्रदूषित करना पसंद नहीं करते हैं (क्योंकि हो सकता है कि यदि आप स्विच में enum का भी उपयोग करते हैं तो संकलक आपको एक लापता केस COUNT की चेतावनी देगा :), आप यह कर सकते हैं:

enum Colour {Red, Green, Blue};
const Colour LastColour = Blue;

Colour co(0);
while (true) {
 //do stuff with co
 //...
  if (co == LastColour) break;
  co = Colour(co+1);
}
0
जोड़ा

यदि आप जानते थे कि enum मान अनुक्रमिक थे, उदाहरण के लिए क्यूटी: कुंजी enum, आप कर सकते हैं:

Qt::Key shortcut_key = Qt::Key_0;
for (int idx = 0; etc...) {
    ....
    if (shortcut_key <= Qt::Key_9) {
        fileMenu->addAction("abc", this, SLOT(onNewTab()),
                            QKeySequence(Qt::CTRL + shortcut_key));
        shortcut_key = (Qt::Key) (shortcut_key + 1);
    }
}

यह उम्मीद के रूप में काम करता है।

0
जोड़ा

मैं अक्सर ऐसा करता हूं

    enum EMyEnum
    {
        E_First,
        E_Orange = E_First,
        E_Green,
        E_White,
        E_Blue,
        E_Last
    }

    for (EMyEnum i = E_First; i < E_Last; i = EMyEnum(i + 1))
    {}

या यदि लगातार नहीं है, लेकिन नियमित कदम (जैसे बिट झंडे) के साथ

    enum EMyEnum
    {
        E_First,
        E_None = E_First,
        E_Green = 0x1,
        E_White = 0x2
        E_Blue  = 0x4,
        E_Last
    }

    for (EMyEnum i = E_First; i < E_Last; i = EMyEnum(i << 1))
    {}
0
जोड़ा

उत्तरों में से एक कहते हैं: "यदि आप जानते थे कि enum मान अनुक्रमिक थे, उदाहरण के लिए क्यूटी: कुंजी enum"।

क्यूटी :: मुख्य मान अनुक्रमिक नहीं हैं । Enum में कुछ खंड हैं।

यह धागा enum में सभी मूल्यों पर पुनरावृत्ति के बारे में है। मेटा ऑब्जेक्ट सिस्टम के उपयोग के कारण यह वास्तव में क्यूटी में संभव है:

const QMetaObject *metaObject = qt_getQtMetaObject();
QMetaEnum keyEnum = metaObject->enumerator(metaObject->indexOfEnumerator("Key"));
for (int i = 0; i < keyEnum.keyCount(); ++i) {
    qDebug() << keyEnum.key(i);
}

QObject :: मेटाऑब्जेक्ट() और Q_ENUM मैक्रो भी देखें।

मुझे लगता है कि इस तरह की चीजें सी ++ 20 के साथ आसान हो जाएंगी? लेकिन मैंने इसमें नहीं देखा है।

0
जोड़ा

बस सरणी पर स्याही और लूप की एक सरणी बनाएं, लेकिन अंतिम तत्व को -1 कहें और बाहर निकलने की स्थिति के लिए इसका उपयोग करें।

अगर enum है:

enum MyEnumType{Hay=12,Grass=42,Beer=39};

फिर सरणी बनाएं:

int Array[] = {Hay,Grass,Beer,-1};

for (int h = 0; Array[h] != -1; h++){
  doStuff( (MyEnumType) Array[h] );
}

जब तक -1 चेक पाठ्यक्रम के तत्वों में से किसी एक के साथ टकरा नहीं जाता है तब तक यह प्रतिनिधित्व में स्याही से कोई फर्क नहीं पड़ता है।

0
जोड़ा