this question का जवाब देने के लिए एक वैरैडिक फ़ॉरवर्डिंग संदर्भ कन्स्ट्रक्टर बनाने की कोशिश करने के बारे में, जिसे केवल कोई अन्य कन्स्ट्रक्टर वैध नहीं माना जाना चाहिए। यही कारण है, अगर वहाँ था एक:फ़ॉलबैक वैरिएडिक कन्स्ट्रक्टर - यह क्यों काम करता है?
C(const char*, size_t) { } // 1
template <typename... T, ???> C(T&&...) { } // 2
हम C c1{"abc", 2};
, (1) फोन करने के लिए आवश्यक रूपांतरण के बावजूद चाहते हैं, लेकिन C c2{1, 2, 3};
, (2) कॉल करने के लिए के रूप में (1) लागू नहीं कर सकते।
मैं निम्नलिखित समाधान का प्रस्ताव:
template <typename... T,
typename = std::enable_if_t<!std::is_constructible<C, T&&...>::value>
>
C(T&&...) { }
और प्रस्तावित द्वारा, मेरा मतलब है, मैं इसे करने की कोशिश की और कहा कि यह वास्तव में काम करता है खोजने के लिए आश्चर्य हुआ। यह संकलित करता है और वही करता है जो मैंने जीसीसी और क्लैंग दोनों के लिए आशा की थी। हालांकि, मुझे की व्याख्या करने के लिए नुकसान हुआ है क्यों यह काम करता है या भले ही यह वास्तव में पर काम करता है और जीसीसी और क्लैंग दोनों ही विशेष रूप से समायोजित होते हैं। क्या यह? क्यूं कर?
मेरी समझ के आधार पर यदि कोई अन्य कन्स्ट्रक्टर 'सी सी 1 {" एबीसी ", 2} के लिए उपलब्ध है;' std :: enable_if_t' की तुलना में कोई मूल्य नहीं होगा, और इसलिए 'टेम्पलेट 'और SFINAE टेम्पलेट कन्स्ट्रक्टर नहीं बनाएगा। –
आपके उत्तर पर मेरी टिप्पणी दोबारा पोस्ट करना: [यह संशोधित उदाहरण] (http://melpon.org/wandbox/permlink/JM2U8pxxvguewhd1) दिखाता है कि डिफ़ॉल्ट तर्क SFINAE * सी * के सभी * कन्स्ट्रक्टर को मानता है, यहां तक कि जिन्हें बाद में घोषित किया जाता है कन्स्ट्रक्टर टेम्पलेट। – dyp
इसके लिए कितना कम मूल्य है, एमएसवीसी 2013 भी इस वाक्यविन्यास को/डब्ल्यू 4 के तहत स्वीकार करता है और जीसीसी के रूप में वही चीज प्रिंट करता है [इस उदाहरण] (http://coliru.stacked-crooked.com/a/1fe984a4ceb6e193), हालांकि यह * करता है * कई डिफ़ॉल्ट रचनाकारों के बारे में चेतावनी देता है, और इंटेलिजेंस ऐसा नहीं लगता है कि 'Foo :: Foo' पर तीसरा कॉल मान्य है। (फिर से, यह वीसी ++ 18 के ठीक होने के बावजूद है) – jaggedSpire