2013-03-23 6 views
13

के बीच अंतर करने के लिए मैं बढ़ावा देने के लिए प्रचार पदोन्नति उपनाम लिख रहा हूं :: प्रचार के लिए लेकिन सी ++ 11 के लिए। इसका उद्देश्य varidic कार्यों से तर्क पुनर्प्राप्त करते समय चेतावनियों से बचने के लिए है। जैसे 1) एक पूर्णांक से छोटी एक पूर्णांक 2 int करने के लिए प्रोत्साहित किया जाता है) एक नाव दोगुनासी ++ 11 प्रकार की विशेषता एनम कक्षा और नियमित enum

करने के लिए प्रोत्साहित किया जाता है कि:

template <typename T> 
std::vector<T> MakeArgVectorV(int aArgCount, va_list aArgList) 
{ 
    std::vector<T> args; 
    while (aArgCount > 0) 
    { 
     args.push_back(static_cast<T>(va_arg(aArgList, Promote<T>))); 
     --aArgCount; 
    } 
    return args; 
} 

टेम्पलेट उर्फ ​​बढ़ावा देना प्रकार variadic तर्क के लिए डिफ़ॉल्ट तर्क पदोन्नति निम्नलिखित को बढ़ावा देता है मेरी समस्या यह है कि एक मानक सी ++ enum पदोन्नत किया जा सकता है लेकिन एक सी ++ 11 enum वर्ग पदोन्नत नहीं किया जाता है (संकलक चेतावनी उत्पन्न नहीं करता है)। मैं एक नियमित enum के साथ काम करने के लिए प्रोत्साहित करना चाहता हूं लेकिन एक सी ++ 11 enum वर्ग अनदेखा।

मैं अपने प्रचार टेम्पलेट उपनाम में एनम कक्षा और एक enum के बीच अंतर कैसे बता सकता हूं?

+1

असली समस्या यह है कि आप 'std :: startizer_list' और/या विविध टेम्पलेट्स के बजाय' va_arg's का उपयोग कर रहे हैं। – Fanael

+0

टिप के लिए धन्यवाद लेकिन मेरे पास va_list है क्योंकि मैं एक सी इंटरफ़ेस के साथ काम कर रहा हूं। – Sam

+0

@ सैम: क्या मेरा जवाब आपकी समस्या को हल कर रहा है? –

उत्तर

21

यहाँ एक संभव समाधान है:

#include <type_traits> 

template<typename E> 
using is_scoped_enum = std::integral_constant< 
    bool, 
    std::is_enum<E>::value && !std::is_convertible<E, int>::value>; 

समाधान के बीच व्यवहार में एक फर्क कारनामे scoped और unscoped enumerations पैरा सी ++ 11 स्टैंडर्ड के 7.2/9 में निर्दिष्ट:

एक गणक का मूल्य या एक unscoped गणना प्रकार की वस्तु अभिन्न पदोन्नति (4.5) द्वारा एक पूर्णांक में परिवर्तित कर दिया गया है। [...] ध्यान दें कि int रूपांतरण के लिए यह अंतर्निहित enum एक स्कॉम्ड गणना के लिए प्रदान नहीं किया गया है।

और यहाँ एक live example है: [...]

यहाँ कैसे आप इसका इस्तेमाल होता है का एक प्रदर्शन है।

आभार: उनका कहना है कि मेरे पिछले दृष्टिकोण केवल तब तक operator + का कोई उपयोगकर्ता-निर्धारित अधिभार नहीं है के रूप में काम करेगा के लिए Daniel Frey करने के लिए

धन्यवाद।

+3

+1, लेकिन एक गुफा है: यह केवल तब तक काम करता है जब तक कि कुछ enum वर्ग 'E' के लेखक ने ** ** ** को अपना 'ऑपरेटर + (int, E) परिभाषित नहीं किया है। 'शून्य डमी (int)' जोड़कर इसे ठीक करें और 'decltype (डमी (std :: declval ()) का उपयोग करें)। –

+1

@DanielFrey: अच्छा बिंदु। असल में मैं एक अलग ऑपरेटर का उपयोग कर सकता हूं, जैसे '^', उपयोगकर्ता द्वारा परिभाषित ऑपरेटर ओवरलोड –

+1

@AndyProwl में हस्तक्षेप करने की संभावना कम करने के लिए: या 'int' ले जाने वाले फ़ंक्शन को कॉल करें। – Fanael

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