2016-10-02 7 views
10

इस उदाहरण (also available on wandbox) पर विचार करें:सी ++ 17 का कटौती 'ऑटो' गैर-प्रकार 'टेम्पलेट' पैरामीटर पैटर्न-मिलान टेम्पलेट स्पष्ट गैर-प्रकार पैरामीटर के साथ कर सकते हैं?

template <template <auto> class> 
void test() { } 

template <int> 
struct X { }; 

पर clang++ 4.0 (ट्रंक) परिणाम एक संकलन त्रुटि में test<X>() का दृष्टांत की कोशिश:

error: no matching function for call to 'test' 
    test<X>(); 
    ^~~~~~~ 

note: candidate template ignored: 
     invalid explicitly-specified argument for 1st template parameter 
void test() { } 

मेरे प्रारंभिक धारणा/अंतर्ज्ञान था कि test का उपयोग किसी भी प्रकार के template से गैर-प्रकार पैरामीटर होने के लिए किया जा सकता है।


हालांकि, निम्नलिखित कोड स्निपेट सफलतापूर्वक संकलित:

template <template <auto> class> 
void test() { } 

//  vvvv 
template <auto> 
struct X { }; 

इस इरादा है? P0127R2 में कुछ भी निर्णायक नहीं मिला।

+0

शीर्षक में, क्या आपका मतलब "घटाया गया" था? –

उत्तर

9

यह निश्चित रूप से इरादा है। टेम्पलेट-टेम्पलेट पैरामीटर केवल टेम्पलेट से मेल खाते हैं जो समान प्रकार के तर्क लेते हैं। यह:

template <template <auto> class> 
void test() { } 

केवल एक वर्ग टेम्पलेट है कि गैर प्रकार पैरामीटर की किसी भी तरह ले जा सकते हैं के साथ instantiated जा सकता है। लेकिन यह:

template <int> 
struct X { }; 

ऐसा वर्ग टेम्पलेट नहीं है। X केवल int के साथ तुरंत चालू किया जा सकता है। यह टेम्पलेट टेम्पलेट पैरामीटर के लिए विनिर्देश से मेल नहीं खाता है, इसलिए त्रुटि। क्या होगा अगर test अपने वर्ग टेम्पलेट को पॉइंटर प्रकार के साथ तुरंत चालू करना चाहता था? या सदस्य के लिए काम या सूचक करने के लिए सूचक? यह असंभव होगा।

template <auto> struct X { }; के साथ आपका दूसरा प्रयास टेम्पलेट-टेम्पलेट पैरामीटर से मेल खाता है, इसलिए यह अच्छी तरह से गठित है। ध्यान दें कि रिवर्स, testtemplate <int> class पैरामीटर लें और template <auto> struct X { }; में गुजरना भी अच्छी तरह से गठित है क्योंकि तर्क पैरामीटर से अधिक सामान्य है।

A template-argument matches a template template-parameterP when each of the template parameters in the template-parameter-list of the template-argument’s corresponding class template or alias template A matches the corresponding template parameter in the template-parameter-list of P . Two template parameters match if they are of the same kind (type, non-type, template), for non-type template-parameters, their types are equivalent (14.5.6.1), and for template template-parameters, each of their corresponding template-parameters matches, recursively.


नोट::


प्रासंगिक शब्दों [temp.arg.template] में है तुल्यता शब्दों auto स्वीकार करता है - auto मामले और auto को खारिज कर दिया - int मामला है, लेकिन int - auto केस (मेरे पढ़ने के आधार पर) को अस्वीकार कर रहा है। मैं इस पर कुछ स्पष्टीकरण प्राप्त करने की कोशिश करने जा रहा हूं।

+0

आपके स्पष्टीकरण अनुरोध के लिए कोई परिणाम? –

+0

@ जोहान्सचैब-लिटब [नोप] (https://groups.google.com/a/isocpp.org/forum/#!topic/std-discussion/xVUfSpP0_48) – Barry

2

बैरी जवाब है, जो मुझे उत्सुक, यहां की गईं के अलावा चार संभव संयोजनों और परिणामों बजना 4.0 (SVN), see also on wandbox का उपयोग कर रहे हैं:

template <bool> struct obj_bool { }; // object taking a value of boolean type 
template <auto> struct obj_auto { }; // object taking a value of deduced type 
//  ^^^^^^ Note: this is a template value argument (non-type template argument) 

template <template <auto> typename> void fn_auto() { } 
template <template <bool> typename> void fn_bool() { } 
//  ^^^^^^^^^^^^^^^^^^^^^^^^ Note: this is a template type argument 
//     ^^^^^^    taking a template value argument 

int main() {  
    fn_bool<obj_bool>(); // #1 bool->bool OK (exact match) 
    fn_auto<obj_auto>(); // #2 auto->auto OK (exact match) 
    fn_bool<obj_auto>(); // #3 bool->auto OK (sub-set) 
    //fn_auto<obj_bool>(); // #4 auto->bool Error: no matching function. 
} 

कि से, # 1 और # 2 सटीक स्पष्ट रूप से कर रहे हैं मैच और उम्मीद के रूप में काम कर रहे हैं।# 3 एक टेम्पलेट पर बूल कार्यान्वयन का आह्वान करेगा जो न केवल बूल को नियंत्रित कर सकता है बल्कि सभी प्रकारों को नियंत्रित कर सकता है, जबकि # 4 किसी ऑब्जेक्ट के साथ सामान्यीकृत ऑब्जेक्ट (ऑटो) की अपेक्षा की परिभाषा का आह्वान करने का प्रयास करेगा, जो संभावनाओं के केवल उप-सेट (बूल) प्रदान करता है ।

टेम्पलेटेड फ़ंक्शन fn_auto किसी भी मूल्य प्रकार (ऑटो) लेने वाले टेम्पलेट्स के लिए संभावित तत्कालताओं का वादा करता है। इस प्रकार यह केवल संभावनाओं का एक उप-सेट दे रहा है (बूल) इस वादे का उल्लंघन करता है।

हालांकि तुरंत स्पष्ट नहीं है, प्रतिबंध समझ में आता है। और मेरे शब्द के लिए खेद है कि सी ++ मानक अनुपालन नहीं है।

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