15

मेरे पास है:कम से कम तर्कों पर एक भिन्न टेम्पलेट टेम्पलेट पैरामीटर विशेषज्ञता: कानूनी या नहीं? कोड

#include <cstdio> 

template<template<typename...> class> 
struct Foo 
{ 
    enum { n = 77 }; 
}; 

template<template<typename, typename...> class C> 
struct Foo<C> 
{ 
    enum { n = 99 }; 
}; 

template<typename...> struct A { }; 

template<typename, typename...> struct B { }; 

int main(int, char**) 
{ 
    printf("%d\n", Foo<A>::n); 
    printf("%d\n", Foo<B>::n); 
} 

विचार है कि template<typename, typename...> classtemplate<typename...> class के एक सबसेट है, तो यह उस पर विशेषज्ञ करने के लिए संभव हो सकता है। लेकिन यह बहुत गूढ़ है, तो शायद नहीं। आइए इसे आज़माएं।

जीसीसी 4.7 का कहना है:

$ g++ -std=c++11 test157.cpp 

यह संकलित!

यह चल रहा है:

$ ./a.out 
77 
99 

यह काम करता है!

बजना 3.1 का कहना है:

$ clang++ -std=c++11 test157.cpp 
test157.cpp:10:8: error: class template partial specialization does not specialize any template argument; to define the primary template, remove the template argument list 
struct Foo<C> 
    ^~~~ 
test157.cpp:9:10: error: too many template parameters in template template parameter redeclaration 
template<template<typename, typename...> class C> 
     ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 
test157.cpp:3:10: note: previous template template parameter is here 
template<template<typename...> class> 
     ^~~~~~~~~~~~~~~~~~~~~ 
2 errors generated. 

कौन सही है?

उत्तर

7

क्लैंग आंशिक विशेषज्ञता को अस्वीकार करने में गलत है। भूलने के तरीके को समझने के लिए, आपको समझने की जरूरत है कि कौन सा झुकाव निदान करता है। इसका मतलब आंशिक विशेषज्ञता का निदान करना है जिसका तर्क प्राथमिक वर्ग टेम्पलेट (<param1, param2, ... , paramN>) की निहित तर्क सूची से मेल खाता है।

हालांकि तर्क सूची अलग-अलग हैं इसलिए क्लैंग इसका निदान नहीं करेगा। विशेष रूप से इसमें हस्तक्षेप करने के लिए कुछ भी नहीं है आंशिक विशेषज्ञता कम या ज्यादा तर्कों से मेल खाता है।

template<typename A, typename B> class C; 
template<typename B, typename A> class C<A, B> {}; 

आंशिक विशेषज्ञता यहां सबकुछ से मेल खाती है और प्राथमिक टेम्पलेट से मेल नहीं खाती है। और दोनों टेम्पलेट्स की तर्क सूचियां अलग-अलग हैं इसलिए यह आंशिक विशेषज्ञता वैध है, बस आप की तरह।

+0

धन्यवाद। आकर्षक उदाहरण। इसके बारे में सोचते हुए, मेरा उदाहरण किसी भिन्न-विशिष्ट संख्या पैरामीटर (कहें, दो) के लिए एक भिन्न टेम्पलेट टेम्पलेट पैरामीटर को विशेषज्ञता देने के सामान्य व्यक्ति का एक विशिष्ट मामला था। यदि मैं 'टेम्पलेट <टाइपनाम, टाइपनाम> कक्षा' के लिए 'Foo' का विशेषज्ञता बनाने का प्रयास करता हूं, तो मुझे वही व्यवहार मिलता है: जीसीसी स्वीकार करता है, क्लैंग अस्वीकार करता है। मैं एक बग फाइल करूंगा (अगर यह नहीं किया गया है)। मानक से एक उद्धरण मुझे खुश कर देगा, अगर यह बहुत अधिक परेशानी नहीं है। – glaebhoerl

4
`template<template<typename, typename...> class C> 

कोई और अधिक

template<template<typename...> class> 

से विशेष उन दोनों अज्ञात प्रकार पैरामीटर की एक सूची लेता है। यह सिर्फ इतना है कि पूर्व इस सूची के एक सदस्य को एक अलग पैरामीटर के रूप में लेता है। इसमें इस प्रकार के बारे में कोई अतिरिक्त जानकारी नहीं है कि संकलक को दूसरे पर एक का चयन करना चाहिए।

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

क्लैंग निदान पर बहुत उत्सुक है, इसलिए मुझे लगता है कि यह असामान्यता को पकड़ रहा है और सही तरीके से त्रुटियां दे रहा है। जीसीसी इसे संकलित करने में सक्षम है अजीब है। हो सकता है क्योंकि आप स्पष्ट रूप से निर्दिष्ट कर रहे हैं कि struct A और struct B में अलग-अलग टेम्पलेट्स का उपयोग करने के लिए, जीसीसी उसको पकड़ने और असामान्यता को दबाने में सक्षम था।

+1

एक अंतर है। उनमें से एक "शून्य या अधिक टाइपनाम पैरामीटर वाले वर्ग टेम्पलेट" से मेल खाता है, अन्य मैचों में "एक या अधिक टाइपनाम पैरामीटर वाले क्लास टेम्पलेट्स"। दरअसल, यदि आप 'टेम्पलेट स्ट्रक्चर ए {}' को टेम्पलेट तर्क के रूप में पास करने का प्रयास करते हैं, जहां पैरामीटर 'टेम्पलेट <टाइपनाम, टाइपनाम ...> क्लास' प्रकार है, तो क्लैंग और जीसीसी दोनों इसे अस्वीकार कर देंगे।बेशक इसका मतलब यह नहीं है कि भाषा मानक भी इस भेद के आधार पर विशेषज्ञता के लिए अनुमति देता है। यदि आप एक उद्धरण प्रदान करते हैं तो मुझे स्वीकार करने में खुशी होगी। – glaebhoerl

+0

एक और तरीका रखें, अगर वे सकारात्मक स्थिति में होने पर तर्कों की संख्या के आधार पर विशेषज्ञता हासिल करना संभव है - 'टेम्पलेट ' बनाम टेम्पलेट <टाइपनाम, टाइपनाम ...> '- मुझे कोई सैद्धांतिक बाधा नहीं दिखती यह एक नकारात्मक स्थिति में होने पर भी अनुमति देता है, 'टेम्पलेट <टेम्पलेट वर्ग>' बनाम टेम्पलेट <टेम्पलेट <टाइपनाम, टाइपनाम ...> वर्ग> '। मैं इस बारे में अनिश्चित हूं कि आईएसओ मानक इसके लिए प्रावधान करता है या नहीं। – glaebhoerl