2011-02-12 11 views
11

मैं निम्नलिखित समस्या के समाधान की एक hacky प्रकार के लिए देख रहा हूँ: जीसीसी 4.4+ निम्नलिखित C++ 0x कोड स्वीकार करता है:"enum वर्ग" अनुकरण या MSVC के लिए ठोस विकल्प 10.0

enum class my_enum 
{ 
    value1, 
    value2 
}; 

कौन सा इस तरह के उपयोग की अनुमति देता है:

my_enum e = my_enum::value1; 

यह सभी घंटियाँ और सीटी के साथ लाता है। मैं इस कोड को एमएसवीसी 2010 के साथ संगत बनाना चाहता हूं, इस प्रभाव के लिए कि उपयोग वाक्यविन्यास नहीं बदलता है। मैंने पहले ही here से पहले इस पर विचार किया है, और स्वीकार्य उत्तर काम करता है, लेकिन enum और enum मूल्यों के लिए दो अलग-अलग नामों की आवश्यकता दो दृष्टिकोणों की संगतता को मार रही है। यह निश्चित रूप से C++ 0x कोड को प्रतिस्थापित करने के लिए अनुपयोगी बनाता है। मुझे आश्चर्य हुआ कि कुछ #undef और #define चालबाजी इस पर काम कर सकती है, जिससे मुझे enum class का उपयोग सिंटैक्स (शायद सख्त प्रकार की सुरक्षा आदि के बिना), लेकिन कम से कम एक ही वाक्यविन्यास का उपयोग कर सकता है। धन्यवाद!

उत्तर

20

मैं बस जेम्स 'अच्छा हैक के साथ एक समस्या की खोज की (मैं पहले की है जो उपयोग कर रहा है), और समस्या के लिए एक फिक्स। जब मैंने my_enum के लिए स्ट्रीम ऑपरेटर को परिभाषित करने का प्रयास किया तो मुझे समस्या मिली।

#include <iostream> 

struct my_enum { 
    enum type { 
     value1, 
     value2 
    }; 

    my_enum(type v) : value_(v) { } 

    operator type() const { return value_; } 

private: 

    type value_; 
}; 

std::ostream& 
operator<<(std::ostream& os, my_enum v) 
{ 
    return os << "streaming my_enum"; 
} 

int main() 
{ 
    std::cout << my_enum::value1 << '\n'; 
} 

उत्पादन होता है:

0 

समस्या my_enum::value1my_enum से अलग प्रकार की है। यहां जेम्स हैक के लिए एक हैक है जिसके साथ मैं आया था।

struct my_enum 
{ 
    static const my_enum value1; 
    static const my_enum value2; 

    explicit my_enum(int v) : value_(v) { } 

    // explicit // if you have it! 
     operator int() const { return value_; } 

private: 

    int value_; 
}; 

my_enum const my_enum::value1(0); 
my_enum const my_enum::value2(1); 

नोट्स:

  1. जब तक अन्यथा एक enum आधार द्वारा निर्दिष्ट, एक scoped गणन के अंतर्निहित प्रकार int है।
  2. अंतर्निहित अभिन्न प्रकार से और उससे स्पष्ट रूपांतरण की अनुमति है। लेकिन निहित रूपांतरण नहीं हैं। अपनी पूरी ताकत से कर।
  3. यह हैक मानों की गणना करने की आवश्यकता के कारण जेम्स की तुलना में एक पिटा से अधिक है। मैं आशा करता हूं कि स्कॉप्ड एनम समर्थन के बिना कंपाइलर्स तेजी से विलुप्त हो जाएंगे!
+0

बहुत अच्छा समाधान। –

+0

कमाल का समाधान। यह विकृत होना चाहिए। – FailedDev

+1

यह दृष्टिकोण कम से कम एमएसवीसी 10 पर 'स्विच'/'केस' की अनुमति नहीं देता है (मुझे" सी 2051: केस अभिव्यक्ति स्थिर नहीं है ")। यह एक बड़ा पिटा है, क्योंकि 'एनम' आमतौर पर इस तरह से उपयोग किया जाता है। –

5

इस समाधान का उपयोग न करें। बेहतर समाधान के लिए हावर्ड द्वारा स्वीकृत उत्तर देखें। मैं इस पोस्ट को यहां छोड़ रहा हूं क्योंकि हॉवर्ड का जवाब इसका संदर्भ देता है।

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

कहा कि, एक हैक समाधान के रूप में, आप एक struct में enum लपेट और अंतर्निहित रूपांतरण की एक जोड़ी का उपयोग कर सकते हैं:

struct my_enum { 
    enum type { 
     value1, 
     value2 
    }; 

    my_enum(type v) : value_(v) { } 

    operator type() const { return value_; } 

private: 

    type value_; 
}; 
+0

क्या यह एक पैटर्न है? आप इसे एक हैक क्यों मानते हैं? यह साफ है। – Inverse

+1

@ इनवर्क्स: यदि आप इसे बार-बार उपयोग करते हैं तो यह एक पैटर्न बन जाएगा :-)। नेमस्पेस प्रदूषण को रोकने के लिए संरचना या नामस्थान में एक गणना को लपेटना एक आम तकनीक है और एक जिसे मैं लगातार (अच्छी तरह से, ज्यादातर) उपयोग करता हूं। Encapsulating संरचना का उपयोग करने के लिए निहित रूपांतरणों का उपयोग करना जैसे कि यह गणना एक सामान्य पैटर्न नहीं है, कम से कम किसी भी कोड में मुझे पढ़ने की खुशी नहीं है। निहितार्थ रूपांतरणों के कारण मैं इससे सावधान हूं: मैं लगातार विभिन्न तरीकों की खोज कर रहा हूं कि निहित रूपांतरण आपको सूक्ष्म टूटी हुई कोड लिखने की अनुमति देते हैं ... –

0

मैं वास्तव में एकदम सही समाधान खोजने के लिए पूरे दिन लड़ रहा हूं, लेकिन ऐसा प्रतीत नहीं होता है।मैं अपने enum कि

  1. परोक्ष एक switch बयान में एक अभिन्न प्रकार के लिए परिवर्तनीय
  2. उपयोग किए जाने योग्य है नहीं गैर प्रकार टेम्पलेट पैरामीटर

में के रूप में

  • करने योग्य निम्नलिखित के साथ आए हैं की जरूरत है हावर्ड हिन्नेंट के समाधान पर बनाया गया कोड:

    struct DataType 
    { 
        struct integral { 
         enum type { None, Single, Double, Int }; 
        }; 
    
        typedef typename integral::type integral_type; 
    
        explicit DataType(integral_type v) : val(v) {} 
        integral_type integral_value() const { return val; } 
    
        bool operator==(const DataType& s) const { return val == s.val; } 
        bool operator!=(const DataType& s) const { return val != s.val; } 
    
        static const DataType None; 
        static const DataType Single; 
        static const DataType Double; 
        static const DataType Int; 
    
    private: 
        integral_type val; 
    }; 
    

    मेंफ़ाइल:

    const DataType DataType::None (DataType::integral::None); 
    const DataType DataType::Single (DataType::integral::Single); 
    const DataType DataType::Double (DataType::integral::Double); 
    const DataType DataType::Int (DataType::integral::Int); 
    

    गैर प्रकार टेम्पलेट पैरामीटर के रूप में:

    template <DataType::integral_type> 
    struct DataTypeTraits; 
    
    template <> 
    struct DataTypeTraits<DataType::integral::Single> 
    { 
        enum { size = 4 }; 
    }; 
    

    एक स्विच में:

    size_t get_size(DataType type) 
    { 
        switch (type.integral_value()) { 
         case DataType::integral::Single: return DataTypeTraits<DataType::integral::Single>::size; 
         case DataType::integral::Double: return DataTypeTraits<DataType::integral::Double>::size; 
         case DataType::integral::Int:  return DataTypeTraits<DataType::integral::Int>::size; 
         default:       throw std::logic_error("Unknown data type."); 
        } 
    } 
    

    नहीं विशेष रूप से महान है, लेकिन उस के रूप में यह हो जाता है के रूप में अच्छा है, मुझे लगता है। ..

  • संबंधित मुद्दे