2013-10-11 15 views
6

हम follwing स्रोत कोड के संकलन में एक अजीब व्यवहार देखा है:सी ++ 11 टेम्पलेट उपनाम टेम्पलेट टेम्पलेट तर्क के रूप में विभिन्न प्रकार की ओर जाता है?

template<template<class> class TT> struct X { }; 
template<class> struct Y { }; 
template<class T> using Z = Y<T>; 

int main() { 
    X<Y> y; 
    X<Z> z; 
    z = y; // it fails here 
} 

यह एक थोड़ा संशोधित C++ टेम्पलेट अन्य नामों के लिए 11 मानक प्रस्ताव से लिया उदाहरण है: http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2007/n2258.pdf (पेज 4 देखें) यह भी ध्यान रखें कि प्रस्ताव "वाई और जेड को उसी प्रकार के होने की घोषणा करता है।" हमारी व्याख्या में इसलिए वाई से ज़ेड (या प्रतिलिपि बनाना) ज़ेड करना संभव होना चाहिए।

हालांकि, यह कोड जीसीसी 4.8.1 के साथ संकलित नहीं है और न ही क्लैंग 3.3 के साथ। क्या यह संकलक में एक त्रुटि है या क्या हमने मानक को गलत समझा है?)

पी.एस.;

अग्रिम, craffael एट अल में धन्यवाद बजना त्रुटि संदेश है:

error: no viable overloaded '=' 

note: candidate function (the implicit copy assignment operator) not viable: no known conversion from 'X<template Y>' to 'const X<template Z>' for 1st argument 
template<template<class> class TT> struct X { }; 

note: candidate function (the implicit move assignment operator) not viable: no known conversion from 'X<template Y>' to 'X<template Z>' for 1st argument 
template<template<class> class TT> struct X { }; 
+0

'वाई' और 'जेड' अलग-अलग * टेम्पलेट-नाम * हैं, क्योंकि वे 'एक्स' के साथ अलग-अलग तत्कालताएं उत्पन्न करते हैं। §14.5.7/1 देखें। – Xeo

उत्तर

8

वर्तमान मानक ऐसा नहीं कहता है, लेकिन इरादा यह है कि वाई और जेड का एक ही प्रकार है। इसके लिए एक खुला कोर वर्किंग ग्रुप मुद्दा है: http://wg21.cmeerw.net/cwg/issue1286

+0

बहुत बहुत धन्यवाद, वास्तव में यह गायब कुंजी थी। मैं बस मानक अधिकार स्कैन कर रहा था और वास्तव में एक संकेत नहीं मिला कि मेरा कोड खराब है। हालांकि मैंने ध्यान दिया कि प्रस्ताव से उदाहरण थोड़ा बदल दिया गया था जो डैनियल फ्री ने सुझाव दिया था। इस तरह के संकेत कि मेरा कोड शायद बीमार है लेकिन यह स्पष्ट रूप से नहीं कहता है (यह मेरी व्याख्या है) वैसे भी मुझे उम्मीद है कि समस्या 1286 इसे अगले मानक में बनाती है ... – craffael

+0

+1 दिलचस्प, तो मेरा जवाब * * सही था लेकिन यह (उम्मीद है) बदलने जा रहा है। जानकार अच्छा लगा! –

+1

समस्या 1244 में यह देखा गया था कि उस उदाहरण का समर्थन करने के लिए कोई शब्द नहीं था, इसलिए कोर वर्किंग ग्रुप ने उदाहरण अपडेट किया। हालांकि, गैबी डॉस रेइस ने तब टिप्पणी की कि वास्तव में मूल उदाहरण के लिए इरादा अच्छी तरह से बनाई गई थी, इसलिए मानक पाठ को अद्यतन करने के लिए 1286 जारी किया गया था (और उदाहरण को वापस बदलें)। – cmeerw

3

मुझे लगता है कि आप एक प्रकार और एक टेम्पलेट (या एक टेम्पलेट उर्फ) भ्रमित कर रहे हैं। आपके पास Y है, जो एक टेम्पलेट और Z है, जो एक और है। यदि आपको लगता है कि Y == Z, तो आप गलत हैं। केवल अगर आप उन्हें प्रकार में बदल देते हैं, तो प्रकार समान हैं, उदा। Y<int>Z<int> जैसा ही प्रकार है। अपने उदाहरण में:

template<class T> struct X { }; 

template<class> struct Y { }; 
template<class T> using Z = Y<T>; 

int main() { 
    X<Y<int>> y; 
    X<Z<int>> z; 
    z = y; // works 
} 

अपने मूल कोड में आप X<Y> और X<Z> के साथ उन्हें करने के लिए भेजा, लेकिन जैसा कि YZ के रूप में ही नहीं है, तो X<Y> और X<Z> विभिन्न प्रकार हैं।

+0

मुझे पता है कि प्रकार और टेम्पलेट समान नहीं हैं और मैं पूरी तरह से सहमत हूं कि आपके उदाहरण को संकलित करना चाहिए। हालांकि यह मानक से अस्पष्ट प्रतीत होता है कि मेरा कोड खराब है या नहीं (cmeerw का जवाब देखें)। – craffael

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