को जोड़ने के लिए जवाब @StackedCrooked के लिए, आप operator++
, operator--
और operator*
ओवरलोड और कार्यक्षमता की तरह इटरेटर हो सकता है। कुछ <algorithm>
टेम्पलेट
void print(Color c) {
std::cout << c << std::endl;
}
int main() {
std::for_each(Color_Begin, Color_End, &print);
}
साथ
enum Color {
Color_Begin,
Color_Red = Color_Begin,
Color_Orange,
Color_Yellow,
Color_Green,
Color_Blue,
Color_Indigo,
Color_Violet,
Color_End
};
namespace std {
template<>
struct iterator_traits<Color> {
typedef Color value_type;
typedef int difference_type;
typedef Color *pointer;
typedef Color &reference;
typedef std::bidirectional_iterator_tag
iterator_category;
};
}
Color &operator++(Color &c) {
assert(c != Color_End);
c = static_cast<Color>(c + 1);
return c;
}
Color operator++(Color &c, int) {
assert(c != Color_End);
++c;
return static_cast<Color>(c - 1);
}
Color &operator--(Color &c) {
assert(c != Color_Begin);
return c = static_cast<Color>(c - 1);
}
Color operator--(Color &c, int) {
assert(c != Color_Begin);
--c;
return static_cast<Color>(c + 1);
}
Color operator*(Color c) {
assert(c != Color_End);
return c;
}
आइए परीक्षण अब, Color
एक निरंतर द्विदिश इटरेटर है। यहां एक पुन: प्रयोज्य वर्ग है जिसे मैंने मैन्युअल रूप से ऊपर करते हुए कोड किया था। मैं इसे, कई और अधिक enums के लिए काम कर सकता था तो एक ही कोड दोहरा देखा फिर से काफी थकाऊ
// Code for testing enum_iterator
// --------------------------------
namespace color_test {
enum Color {
Color_Begin,
Color_Red = Color_Begin,
Color_Orange,
Color_Yellow,
Color_Green,
Color_Blue,
Color_Indigo,
Color_Violet,
Color_End
};
Color begin(enum_identity<Color>) {
return Color_Begin;
}
Color end(enum_identity<Color>) {
return Color_End;
}
}
void print(color_test::Color c) {
std::cout << c << std::endl;
}
int main() {
enum_iterator<color_test::Color> b = color_test::Color_Begin, e;
while(b != e)
print(*b++);
}
कार्यान्वयन इस प्रकार है।
template<typename T>
struct enum_identity {
typedef T type;
};
namespace details {
void begin();
void end();
}
template<typename Enum>
struct enum_iterator
: std::iterator<std::bidirectional_iterator_tag,
Enum> {
enum_iterator():c(end()) { }
enum_iterator(Enum c):c(c) {
assert(c >= begin() && c <= end());
}
enum_iterator &operator=(Enum c) {
assert(c >= begin() && c <= end());
this->c = c;
return *this;
}
static Enum begin() {
using details::begin; // re-enable ADL
return begin(enum_identity<Enum>());
}
static Enum end() {
using details::end; // re-enable ADL
return end(enum_identity<Enum>());
}
enum_iterator &operator++() {
assert(c != end() && "incrementing past end?");
c = static_cast<Enum>(c + 1);
return *this;
}
enum_iterator operator++(int) {
assert(c != end() && "incrementing past end?");
enum_iterator cpy(*this);
++*this;
return cpy;
}
enum_iterator &operator--() {
assert(c != begin() && "decrementing beyond begin?");
c = static_cast<Enum>(c - 1);
return *this;
}
enum_iterator operator--(int) {
assert(c != begin() && "decrementing beyond begin?");
enum_iterator cpy(*this);
--*this;
return cpy;
}
Enum operator*() {
assert(c != end() && "cannot dereference end iterator");
return c;
}
Enum get_enum() const {
return c;
}
private:
Enum c;
};
template<typename Enum>
bool operator==(enum_iterator<Enum> e1, enum_iterator<Enum> e2) {
return e1.get_enum() == e2.get_enum();
}
template<typename Enum>
bool operator!=(enum_iterator<Enum> e1, enum_iterator<Enum> e2) {
return !(e1 == e2);
}
आप कॉल के लिए फ़ंक्शन चुनने का अनुमान कैसे लगाते हैं? क्या आप कुछ छद्म कोड पोस्ट कर सकते हैं आप इसे कैसे मानते हैं? यह आपकी मदद करने में हमारी मदद कर सकता है। –
क्रिल – jameszhao00
के लिए अपडेट किया गया रनटाइम के लिए http://stackoverflow.com/questions/1292426/is-there-any-well-known-paradigm-for-iterating-through-enum पर देखें। (यदि यह संकलन-समय के लिए नहीं था, तो आपका प्रश्न इसका सटीक डुप्लिकेट होगा।) – sbi