2012-06-15 27 views
26

मैं कुछ इनपुट चेकर का निर्माण कर रहा हूं जिसमें पूर्णांक और/या डबल के लिए विशिष्ट फ़ंक्शन होना आवश्यक है (उदाहरण के लिए 'isPrime' केवल पूर्णांक के लिए उपलब्ध होना चाहिए)।std :: enable_if: पैरामीटर बनाम टेम्पलेट पैरामीटर

अगर मैं enable_if एक पैरामीटर के रूप उपयोग कर रहा हूँ यह पूरी तरह काम कर रहा है:

template <class T> 
class check 
{ 
public: 
    template< class U = T> 
    inline static U readVal(typename std::enable_if<std::is_same<U, int>::value >::type* = 0) 
    { 
     return BuffCheck.getInt(); 
    } 

    template< class U = T> 
    inline static U readVal(typename std::enable_if<std::is_same<U, double>::value >::type* = 0) 
    { 
     return BuffCheck.getDouble(); 
    } 
}; 

लेकिन अगर मैं एक टेम्पलेट परमाटर के रूप में यह उपयोग कर रहा हूँ (के रूप में http://en.cppreference.com/w/cpp/types/enable_if पर प्रदर्शन किया)

template <class T> 
class check 
{ 
public: 
    template< class U = T, class = typename std::enable_if<std::is_same<U, int>::value>::type > 
    inline static U readVal() 
    { 
     return BuffCheck.getInt(); 
    } 

    template< class U = T, class = typename std::enable_if<std::is_same<U, double>::value>::type > 
    inline static U readVal() 
    { 
     return BuffCheck.getDouble(); 
    } 
}; 

तो मैं निम्न त्रुटि है:

error: ‘template<class T> template<class U, class> static U check::readVal()’ cannot be overloaded 
error: with ‘template<class T> template<class U, class> static U check::readVal()’ 

मैं ओ नहीं समझ सकता दूसरे संस्करण में क्या गलत है।

+0

संभवतः अप्रासंगिक लेकिन VS2010 में मैं नहीं कर सकता है कि क्योंकि डिफ़ॉल्ट टेम्पलेट तर्क केवल वर्ग टेम्पलेट्स के लिए अनुमति दी जाती है - मैं जी ++ – David

+2

के बारे में पता नहीं है यह पंडिताऊ है, लेकिन 'inline' कीवर्ड पर एक सदस्य विधि या टेम्पलेट की आवश्यकता नहीं है और निश्चित रूप से कोई सदस्य नहीं है जो टेम्पलेट भी है ;-) – AJG85

उत्तर

31

डिफ़ॉल्ट टेम्पलेट तर्क टेम्पलेट के हस्ताक्षर का हिस्सा नहीं हैं (इसलिए दोनों परिभाषाएं एक ही टेम्पलेट को दो बार परिभाषित करने का प्रयास करती हैं))। हालांकि, उनके पैरामीटर प्रकार हस्ताक्षर का हिस्सा हैं। तो तुम क्या कर सकते हैं

template <class T> 
class check 
{ 
public: 
    template< class U = T, 
      typename std::enable_if<std::is_same<U, int>::value, int>::type = 0> 
    inline static U readVal() 
    { 
     return BuffCheck.getInt(); 
    } 

    template< class U = T, 
      typename std::enable_if<std::is_same<U, double>::value, int>::type = 0> 
    inline static U readVal() 
    { 
     return BuffCheck.getDouble(); 
    } 
}; 
+1

+1, मुझे लगता है कि यह अन्य दृष्टिकोण की तुलना में अधिक स्वच्छ दिखता है। – ildjarn

+0

सुंदर चालाक समाधान! – plasmacel

+1

तो एक डिफ़ॉल्ट प्रकार टेम्पलेट पैरामीटर (जिसमें एक डिफ़ॉल्ट प्रकार है) टेम्पलेट के हस्ताक्षर का हिस्सा नहीं है, लेकिन एक डिफ़ॉल्ट गैर-प्रकार टेम्पलेट पैरामीटर (जिसमें एक डिफ़ॉल्ट निरंतर अभिन्न मूल्य है) है। क्या वो सही है? – Alan

7

समस्या यह है कि संकलक एक ही विधि के 2 अधिभार देखता है, दोनों में एक ही तर्क (कोई भी, इस मामले में) और एक ही वापसी मूल्य नहीं होता है। आप ऐसी परिभाषा प्रदान नहीं कर सकते हैं। यह करने के लिए स्पष्ट तरीका फ़ंक्शन द्वारा दिया गया मूल्य पर SFINAE उपयोग करने के लिए है:

template <class T> 
class check 
{ 
public: 
    template< class U = T> 
    static typename std::enable_if<std::is_same<U, int>::value, U>::type readVal() 
    { 
     return BuffCheck.getInt(); 
    } 

    template< class U = T> 
    static typename std::enable_if<std::is_same<U, double>::value, U>::type readVal() 
    { 
     return BuffCheck.getDouble(); 
    } 
}; 

इस तरह, आप 2 अलग भार के प्रदान कर रहे हैं। एक int int देता है, दूसरा एक डबल देता है, और केवल एक निश्चित टी

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