2012-11-20 19 views
5

मैं कुछ SFINAE सुविधाओं के साथ काम कर रहा हूं; वर्तमान में एक ऐसे एप्लिकेशन के हिस्से में जो लिनक्स और विंडोज में चलाना चाहिए; संकलक विकल्प विंडोज अनुप्रयोगों के लिए एमएसवीसी (विजुअल स्टूडियो 2010 10.0) और लिनक्स के लिए जीसीसी 4.4.5 हैं।एक वर्ग के अंदर किसी विशेष प्रोटोटाइप की विधि मौजूद है या नहीं?

अगर कुछ दिया वस्तु कुछ कार्यों के लिए एक कस्टम क्रमांकन करते हैं और इस कार्यों कॉल करें, या एक सरल memcpy और sizeof(Object) करना है, जबकि कस्टम क्रमांकन तरीकों प्रदान न किए गए प्रदान करता है मैं जांच करना चाहिए।

समस्या

है कि कोड का एक टुकड़ा चेतावनी है और न ही MSVC में त्रुटियों के बिना संकलन लेकिन जीसीसी के साथ संयोजित करते समय, कोड निम्नलिखित है:

template 
    < 
     typename Type, 
     typename Return, 
     typename Parameter, 
     Return (Type::*Pointer)(Parameter) const 
    > struct sMemberMethodConst { }; 

template 
    < 
     typename Type, 
     typename Return, 
     typename Parameter, 
     Return (Type::*)(Parameter) 
    > struct sMemberMethod { }; 

template<typename T> struct sMemberMethodChecker 
{ 
    template <typename Type> static char HasCustomSizeMethod(sMemberMethodConst<Type, size_t, void, &Type::Size> *); 
    template <typename Type> static long HasCustomSizeMethod(...); 
    template <typename Type> static char HasSerializeMethod(sMemberMethodConst<Type, size_t, void * const, &Type::Serialize> *); 
    template <typename Type> static long HasSerializeMethod(...); 
    template <typename Type> static char HasDeserializeMethod(sMemberMethod<Type, size_t, const void * const, &Type::Deserialize> *); 
    template <typename Type> static long HasDeserializeMethod(...); 
    // Other specific method checks... 

    enum 
    { 
     HAS_CUSTOM_SIZE_METHOD = (sizeof(HasCustomSizeMethod<T>(0)) == sizeof(char)), 
     HAS_SERIALIZE_METHOD =  (sizeof(HasSerializeMethod<T>(0)) == sizeof(char)), 
     HAS_DESERIALIZE_METHOD = (sizeof(HasDeserializeMethod<T>(0)) == sizeof(char)), 
     IS_CUSTOM =     HAS_CUSTOM_SIZE_METHOD && 
            HAS_SERIALIZE_METHOD && 
            HAS_DESERIALIZE_METHOD, 
     // Other 'shortcuts'... 
    }; 

और त्रुटि है कि मैं जीसीसी के साथ संयोजित करते समय हो रही है है:

invalid parameter type 'void' in declaration template<class Type, class Return, class Parameter, Return (Type::* Pointer)(Parameter)const>

struct sMemberMethodChecker की पहली पंक्ति में

। मुझे पूरा यकीन है कि मुझे typename नहीं है और न ही शब्दों को गलत स्थानांतरित कर रहा है लेकिन मुझे समझ में नहीं आता कि मुझे त्रुटि क्यों मिल रही है और त्रुटि को समझ में नहीं आता है।

मुझे पता है कि एमएसवीसी मानक के साथ लक्स है जबकि जीसीसी मानक अच्छी तरह से अनुरूप है इसलिए मुझे आश्चर्य है कि समस्या एमएसवीसी पक्ष में है जो मूर्ख कोड की अनुमति देता है!

यहाँ प्रश्न हैं:

  • मैं क्यों struct sMemberMethodChecker में invalid parameter type 'void' त्रुटि मिल रहा है?।
  • एमएसवीसी में कोड मान्य क्यों है लेकिन जीसीसी में अवैध है?
  • क्या यह कोड गैर मानक है?
  • क्या SFINAE ट्रिकरी सी ++ 11 से अनन्य है?
+0

क्या 'कॉन्स्ट शून्य * कॉन्स' की अनुमति है? आप संकलक को बता रहे हैं कि आपके पास ऑब्जेक्ट का 'कॉन्स्ट शून्य' प्रकार है। लेकिन वायड्स को किसी भी तरह से संशोधित नहीं किया जा सकता है? यदि आप 'शून्य * const' आज़माते हैं तो क्या होता है? – RedX

+3

अच्छा सवाल। ऐसा लगता है कि जीसीसी स्वीकार नहीं कर रहा 'टेम्पलेट < typename प्रकार, typename वापसी, typename पैरामीटर, वापसी (प्रकार :: *) (' ** शून्य ** ') > struct sMemberMethod {};' के रूप में पैरामीटर । जबकि, एमएसवीसी इसके बारे में उदार है। – iammilind

+1

मुझे विश्वास है कि iammilind सही है। सी के विपरीत, सी ++ फ़ंक्शन की तर्क सूची में 'शून्य' की अनुमति नहीं देता है। ऐसा इसलिए है क्योंकि सी में, 'f() 'प्रोटोटाइप (= पैरामीटर निर्दिष्ट नहीं किए बिना) के बिना एक फ़ंक्शन है, जबकि सी ++ में,' f()' कोई तर्क नहीं है। – Angew

उत्तर

2

मैं struct sMemberMethodChecker में अमान्य पैरामीटर प्रकार 'शून्य' त्रुटि क्यों हो रही है ?.

एमएसवीसी में कोड मान्य क्यों है लेकिन यह जीसीसी में नहीं है?

मेरा मानना ​​है कि एमएसवीसी सहायक है हालांकि जीसीसी इस विशेष कोड में कड़ी मेहनत कर रहा है। चूंकि यह किसी भी तरह Return (Type::*)(void) की अनुमति नहीं दे रहा है। हालांकि सटीक कारण जानने के लिए इसे और अधिक खोदने की जरूरत है।

क्या यह कोड मानक नहीं है?

तब तक नहीं कह सकता जब तक यह संकलित नहीं होता है। और SFINAE जैसी सुविधाओं के लिए मानक खोजना हर किसी के कप चाय नहीं है।

क्या सीएफआईएईई ट्रिकरी सी ++ 11 से अनन्य है?

बिलकुल नहीं। SFINAE C++ 11 से पहले मौजूद था।एक खास प्रकार सदस्य विधि इसके अंदर मौजूद है या नहीं अगर

template<typename ClassName, typename ClassMethodType> 
struct HasMethod 
{ 
    template<typename Type, Type Object> struct Contains; 
    typedef char (&yes)[2]; 

    template<typename Class, typename MethodType> 
    static yes Check (Contains<MethodType, &Class::size>*); 
    template<typename Class, typename MethodType> 
    static char Check (...); 

    static const bool value = (sizeof(Check<ClassName,ClassMethodType>(0)) == sizeof(char)); 
}; 

HasMethod<ClassName, ClassMethodType>::value आप इस सवाल का जवाब देता है:
यहाँ तुम क्या करना चाहते हैं की सरलीकृत तरीका है।
अब तक HasMethod<> उपयोगकर्ता द्वारा प्रदान किए गए प्रकार के साथ विधि नामकरणsize के लिए विशिष्ट है। लेकिन आप उपरोक्त कोड के लिए एक मैक्रो बना सकते हैं और फ़ंक्शन नाम कॉन्फ़िगर करने योग्य बना सकते हैं।

यहां एक working demo with g++ है।

+1

बहुत अच्छे जवाब! दुर्भाग्यवश उदाहरण कोड बिल्कुल ठीक नहीं है जो मुझे चाहिए लेकिन मुझे मुख्य समस्या को हल करने के लिए निर्देशित किया गया है, बीटीडब्ल्यू: मेरी खराब अंग्रेजी को सुधारने के लिए धन्यवाद;) –

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

  • कोई संबंधित समस्या नहीं^_^