टेम्पलेट टेम्पलेट क्लास के साथ जीसीसी / सी ++ 17 में समस्या


10

ओवरलोड के बाद 2 पर विचार करें

template<typename T>
bool test() {
    return true;
}

template<template<typename ...> class T>
bool test() {
    return false;
}

1 वाला नियमित कक्षाओं के लिए काम करता है, जबकि दूसरा एक ऐसे टेम्प्लेट्स के लिए काम करता है जो तात्कालिक नहीं हैं। उदाहरण के लिए:

    std::cout<<test<int>()<<std::endl; <-- this yields 1
    std::cout<<test<std::list>()<<std::endl; <--this yields 0

अब निम्नलिखित टेम्पलेट फ़ंक्शन पर विचार करें:

template<typename U>
bool templfun(){
    struct A{
        bool f(){
            return test<A>(); // <-- this gives an error
        }
    };
    return test<A>();  // <-- this is ok
}

जीसीसी में यह अस्पष्ट अधिभार संकल्प के लिए एक त्रुटि देता है, जबकि क्लैंग संकलन करता है। दिलचस्प बात यह है कि परीक्षण के लिए दूसरा कॉल () जीसीसी (यहां तक ​​कि) में भी त्रुटि पैदा नहीं करता है। इसके अलावा, अगर मैं template<typename U>टेम्पलफुन के ऊपर की चीज को हटाता हूं, तो जीसीसी शिकायत करना बंद कर देता है।

क्या यह जीसीसी के साथ एक बग है या यह अवैध कोड है?

जवाबों:


4

जीसीसी गलत है; struct Aएक टेम्प्लेटेड इकाई है, लेकिन स्पष्ट रूप से एक टेम्पलेट नहीं है (क्योंकि यह एक templateकीवर्ड से शुरू नहीं होता है ), इसलिए कोई अस्पष्टता नहीं है।

पुष्टि करने के लिए, हम यह देखने के लिए टाइप पैरामीटर का नाम बदल सकते हैं कि G ++ टेम्प्लेट-टेम्प्लेट अधिभार का उपयोग करने का प्रयास कर रहा है।

template <typename X>
bool test() {
    return true;
}

template <template <typename...> class Y>
bool test() {
    return false;
}

template <typename U>
bool templfun() {
    struct A {
        bool f() {
            return test<A>(); // <-- this gives an error
        }
    };
    return test<A>(); // <-- this is ok
}

bool run() {
    return templfun<int>();
}

G ++ आउटपुट: ( गॉडबोल्ट से लिंक )

<source>:15:27: error: call of overloaded 'test<templfun() [with U = int]::A>()' is ambiguous
   15 |             return test<A>(); // <-- this gives an error
      |                    ~~~~~~~^~

<source>:2:6: note: candidate: 'bool test() [with X = templfun() [with U = int]::A]'
    2 | bool test() {
      |      ^~~~

<source>:7:6: note: candidate: 'bool test() [with Y = templfun()::A]'
    7 | bool test() {
      |      ^~~~

स्पष्ट रूप से " candidate: 'bool test() [with Y = templfun()::A]'" फर्जी है।

ध्यान दें कि C ++ 11 (C ++ 03 types 14.3.1.2 देखें) से पहले स्थानीय प्रकारों को टेम्पलेट तर्क के रूप में अनुमति नहीं दी गई थी, ताकि G ++ कार्यान्वयन की जटिलता को समझा जा सके।

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.