हम सी ++ 11-तैयार कंपाइलर्स के लिए हमारे सभी कंपाइलर्स (अगले दो वर्षों के आसपास) माइग्रेट करने जा रहे हैं।क्या यह पैटर्न C++ 03 enum से C++ 11 enum क्लास में स्रोत पिछड़े-संगत माइग्रेशन के लिए ठीक है?
हमारे ग्राहक हमारे शीर्षलेखों का उपयोग करेंगे, और अब हम अपने नए एपीआई के लिए शीर्षकों (स्क्रैच से अधिक या कम) लिखने की स्थिति पर हैं।
तो हमें सी ++ 03 एनम्स (उनके सभी मौसाओं के साथ) रखने के बीच चयन करना होगा, या सी ++ 11 नोटेशन अनुकरण करने के लिए एक रैपिंग क्लास का उपयोग करना होगा क्योंकि अंत में, उन एनम्स को सी + +11।
क्या "LikeEnum" मुहावरे एक व्यवहार्य समाधान के नीचे प्रस्तावित है, या क्या इसके पीछे छिपे हुए अप्रत्याशित आश्चर्य हैं?
template<typename def, typename inner = typename def::type>
class like_enum : public def
{
typedef inner type;
inner val;
public:
like_enum() {}
like_enum(type v) : val(v) {}
operator type() const { return val; }
friend bool operator == (const like_enum & lhs, const like_enum & rhs) { return lhs.val == rhs.val; }
friend bool operator != (const like_enum & lhs, const like_enum & rhs) { return lhs.val != rhs.val; }
friend bool operator < (const like_enum & lhs, const like_enum & rhs) { return lhs.val < rhs.val; }
friend bool operator <= (const like_enum & lhs, const like_enum & rhs) { return lhs.val <= rhs.val; }
friend bool operator > (const like_enum & lhs, const like_enum & rhs) { return lhs.val > rhs.val; }
friend bool operator >= (const like_enum & lhs, const like_enum & rhs) { return lhs.val >= rhs.val; }
};
कौन सा हमें उपयोगकर्ता कोड में अवांछनीय परिवर्तन की जरूरत के बिना हमारे enums को उन्नत करने के लिए सक्षम होगा:
// our code (C++03) | our code C++11
// --------------------------------------+---------------------------
|
struct KlingonType | enum class Klingon
{ | {
enum type | Qapla,
{ | Ghobe,
Qapla, | Highos
Ghobe, | } ;
Highos |
} ; |
} ; |
|
typedef like_enum<KlingonType> Klingon ; |
|
// --------------------------------------+---------------------------
// client code (both C++03 and C++11)
void foo(Klingon e)
{
switch(e)
{
case Klingon::Qapla : /* etc. */ ; break ;
default : /* etc. */ ; break ;
}
}
नोट: LikeEnum द्वारा Type Safe Enum idiom
नोट 2 प्रेरित था : स्रोत संगतता int में अंतर्निहित रूपांतरण की वजह से संकलन त्रुटि को कवर नहीं करती है: जिन्हें अवांछित समझा जाता है, और ग्राहक को सलाह में अधिसूचित किया जाएगा एन्से-टू-इंटीजर रूपांतरण को स्पष्ट करने के लिए।
दो-से 'आंतरिक' एक 'टेम्पलेट' फ़ंक्शन बनाएं जो SFINAE सुनिश्चित करता है कि अनुरोध किए गए प्रश्न में प्रकार 'आंतरिक' है जो एक-उपयोगकर्ता एक-निहित रूपांतरण से बचने के लिए है? या एक मध्यवर्ती प्रकार का उपयोग करें? सुरक्षित-मूर्ख मुहावरे और मूल रूप से समस्या ... (या वह मुद्दा 'enum's' पर लागू नहीं होगा? – Yakk