6

निम्नलिखित कोड है, जो वर्ग टेम्पलेट 'विशेष', सदस्य समारोह सूचक प्रकार की वापसी प्रकार के आधार पर विशेषज्ञ के लिए प्रयास करता, VC9 साथ एक संकलन त्रुटि में परिणाम:वर्ग टेम्पलेट आंशिक विशेषज्ञता सदस्य समारोह वापसी प्रकार पर parametrized

template<class F> struct special {}; 
template<class C> struct special<void(C::*)()> {}; 
template<class R, class C> struct special<R(C::*)()> {}; 

struct s {}; 

int main() 
{ 
    special<void(s::*)()> instance; 
    return 0; 
} 

त्रुटि C2752: 'विशेष': http://ideone.com/ekWGg
: एक से अधिक आंशिक विशेषज्ञता टेम्पलेट तर्क सूची

एक ही कोड के रूप में द्वारा दिखाए गए, जीसीसी-4.3.4 द्वारा स्वीकार किया जाता से मेल खाता हैक्या यह वीसी 9 में एक बग है और यदि ऐसा है, तो क्या यह बग वीसी 10 में बनी हुई है?

मैं लेकिन एक horrendously घुसपैठ वैकल्पिक हल (। इस विशिष्ट उपयोग के मामले में कम से कम और अधिक सामान्य समाधान का स्वागत के लिए) के साथ आए हैं:

#include <boost/function_types/result_type.hpp> 
#include <boost/type_traits/is_same.hpp> 

template<typename F, typename R> 
struct is_result_same : 
    boost::is_same< 
    typename boost::function_types::result_type<F>::type, 
    R 
    > 
{}; 

template<class F, bool = is_result_same<F, void>::value> 
struct special {}; 

template<class R, class C> struct special<R(C::*)(), true> {}; 
template<class R, class C> struct special<R(C::*)(), false> {}; 
+0

मैं कल्पना यह है वर्ग टेम्पलेट विशेषज्ञता की तुलना में अधिक विशिष्ट है क्योंकि आर 'शून्य' होने के मामले को हल करते समय दोनों विशेषज्ञताओं के हस्ताक्षर वास्तव में वही हैं ... 'टाइपनाम' कीवर्ड का कुछ चालाक उपयोग मदद कर सकता है लेकिन मैं इस समय कुछ भी चालाक नहीं सोच सकता। – AJG85

उत्तर

3

यह एक बग है।

template <class C> void f(special<void(C::*)()>);  // func-template 3 
template <class R, class C> void f(special<R(C::*)()>); // func-template 4 

अनुसार 14.5.5.2 के लिए, आंशिक:

template <class C> struct special<void(C::*)()>;  // specialization 1 
template <class R, class C> struct special<R(C::*)()>; // specialization 2 

14.5.4.2 के अनुसार, इन दो वर्ग टेम्पलेट विशेषज्ञताओं का आंशिक आदेश इन काल्पनिक समारोह टेम्पलेट्स के आंशिक आदेश के रूप में ही कर रहे हैं इन दो फ़ंक्शन टेम्पलेट्स का ऑर्डरिंग प्रत्येक प्रकार की टेम्पलेट पैरामीटर के लिए आविष्कृत प्रकारों को प्रतिबिंबित करने और अन्य फ़ंक्शन टेम्पलेट में उस तर्क सूची का उपयोग करके टेम्पलेट तर्क कटौती का प्रयास करके निर्धारित किया जाता है।

// Rewrite the function templates with different names - 
// template argument deduction does not involve overload resolution. 
template <class C> void f3(special<void(C::*)()>); 
template <class R, class C> void f4(special<R(C::*)()>); 

struct ty5 {}; struct ty6 {}; struct ty7 {}; 
typedef special<void(ty5::*)()> arg3; 
typedef special<ty6 (ty7::*)()> arg4; 

    // compiler internally tests whether these are well-formed and 
    // the resulting parameter conversion sequences are "exact": 
    f3(arg4()); 
    f4(arg3()); 

टेम्पलेट तर्क कटौती का विवरण 14.8.2 में है। वैध कटौती में से template_name<dependent_type> और dependent_type1 (dependent_type2::*)(arg_list) से हैं। तो f4(arg3()) कटौती सफल होती है, f4<void,ty5>(arg3()); को कम करती है। f3(arg4()) कटौती स्पष्ट रूप से सफल नहीं हो सकती है, क्योंकि void और ty6 एकजुट नहीं है।

इसलिए समारोह टेम्पलेट 3 समारोह टेम्पलेट 4. और वर्ग टेम्पलेट विशेषज्ञता की तुलना में अधिक विशिष्ट है 1 2. तो special<void(s::*)()> हालांकि मैचों दोनों विशेषज्ञताओं, यह स्पष्ट रूप से विशेषज्ञता को दर्शाता है 1.

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