2012-11-12 29 views
5

के होने की जाँच करने के लिए मैं अगर एक वर्ग इस तरह एक विशेष सदस्य समारोह (एक और उदाहरण में यहां पाया) है एक टेम्पलेट के विशेषज्ञ करने का प्रयास करें: जब तक AnyFunc ओवरलोड हो गया हैटेम्पलेट अतिभारित सदस्य समारोह

template <typename T> 
class has_begin 
{ 
    typedef char one; 
    typedef long two; 

    template <typename C> static one test(decltype(&C::AnyFunc)) ; 
    template <typename C> static two test(...); 

public: 
    enum { value = sizeof(test<T>(0)) == sizeof(char) }; 
    enum { Yes = sizeof(has_begin<T>::test<T>(0)) == 1 }; 
    enum { No = !Yes }; 
}; 

यह अच्छी तरह से काम करता है :

class B : public vector<int> 
{ 
public: 
    void AnyFunc() const; 
    void AnyFunc(); 
}; 

मैं अपने टेम्पलेट से "हां" प्राप्त करने के लिए अपने परीक्षण कोड को फिर से लिख सकता हूं?

+0

अच्छा सवाल। एक बहुत छोटी समस्या जो SFINAE के कारण चुपचाप ज्ञात नहीं जा सकती है। – iammilind

उत्तर

1

मिले संस्करण है जो काम करता है:

template <typename C> static one test(decltype(((C*)0)->AnyFunc())*) ; 

आप उस वस्तु स्थिरांक समारोह, इस का उपयोग किया गया है सत्यापित करने के लिए करना चाहते हैं:

template <typename C> static one test(decltype(((const C*)0)->AnyFunc())*) ; 

इस संस्करण का पता नहीं लगा होगा तर्क के साथ समारोह:

class B : public std::vector<int> 
{ 
public: 
    //void AnyFunc() const; 
    //void AnyFunc(); 
    int AnyFunc(int); 
}; 
+1

@ क्लोस यही कारण है कि मैंने 'decltype()' के बाद '*' जोड़ा है ... मैंने जांच की है कि यह पोस्ट करने से पहले काम करता है: http://ideone.com/8Tli7t – PiotrNycz

+0

दूसरा जवाब पढ़ने के बाद, मुझे आपका समाधान चलाने का समाधान मिला मेरे पर्यावरण में आपका बहुत बहुत धन्यवाद! – Klaus

+0

हां, मैं अस्वीकार के बाद * भूल गया! मेरी गलती के लिए खेद है! मुझे दूसरे जवाब से std :: add_pointer के पीछे देखने के बाद यह काम करने के लिए मिला। – Klaus

2

तर्क के बिना ओवरलोडेड फ़ंक्शन नाम का उपयोग (13.4p1) को गायन के लिए हल किया जाना चाहिए ले अधिभार (13.4 पी 4), अन्यथा प्रतिस्थापन विफलता होगी।

आप एक सदस्य समारोह के अस्तित्व के लिए परीक्षण कर रहे हैं तो आप तर्क आप से कॉल करने की योजना है पता होना चाहिए:

template <typename C> static one test(
     typename std::add_pointer<decltype(std::declval<C>().AnyFunc())>::type); 

सामान्य तौर पर, यदि आप एक variadic टेम्पलेट और एक पैटर्न result_of के लिए इसी तरह उपयोग कर सकते हैं :

template <typename C, typename... Args> static one test(
     typename std::add_pointer<decltype(
      std::declval<C>(std::declval<Args>()...).AnyFunc())>::type); 

add_pointer का उपयोग करते हुए इस समारोह वापसी प्रकार है कि समारोह तर्क प्रकारों के रूप में स्वीकार्य नहीं हैं के साथ काम करने की अनुमति देता है (उदाहरण के लिए void)।

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