2010-09-22 8 views
16

this problem को हल करने का प्रयास करके, मुझे कुछ आश्चर्य हुआ। निम्नलिखित कोड पर विचार करें:संदर्भ ढहने?

template <typename T> 
struct foo 
{ 
    foo(T const& x) : data(x) {} 
    T data; 
}; 

ऐसा लगता है कि मैं बिना किसी त्रुटि के प्रकार foo<T const&> की एक वस्तु का निर्माण कर सकते, काल्पनिक T const& const&T const& के रूप में समझा जा रहा है।

ऐसा लगता है कि इसे संदर्भ पर गिरने के संदर्भ में कहा जाता है, लेकिन मैंने पहले इस शब्द को कभी नहीं सुना (लिंक किए गए प्रश्न में टिप्पणियां देखें)।

क्या यह व्यापक है? क्या यह मानक है?

+0

+1। मेरे पास इस पर कुछ होमवर्क है, thx –

+0

मैं इस तरह के प्रश्न को लिंक करना चाहता हूं: http://stackoverflow.com/questions/4144234/c-template-instantiation-with-reference-type –

उत्तर

19

सी ++ 03 में, यह निम्नलिखित

typedef int &ref; 
ref &r = ...; // reference to reference! 

यह अक्सर वास्तव में सख्त या उससे अधिक के साथ संकलन लोगों के लिए समस्याओं का कारण बनता करना वैध नहीं था सी ++ 03 कंपाइलर्स (जीसीसी 4.1 के साथ-साथ कॉमौ 8/4/03 उपरोक्त पसंद नहीं करते हैं) क्योंकि मानक फ़ंक्शन ऑब्जेक्ट बाइंडर्स "संदर्भ के संदर्भ" स्थिति का ख्याल नहीं रखते हैं, और कभी-कभी ऐसे अवैध प्रकार बनाते हैं।

सी ++ 0x में इसे "संदर्भ ढहने" कहा जाता है, हां। अधिकांश मौजूदा सी ++ 03 कंपाइलर्स ऐसा करते हैं (i.e T& जहां T संदर्भ प्रकार को T दोबारा इंगित करता है), नियम को पुन: सक्रिय रूप से लागू करके। boost.call_traits लाइब्रेरी हालांकि इस तरह के फ़ंक्शन पैरामीटर घोषित करना आसान बनाता है, ताकि "संदर्भ का संदर्भ" स्थिति न हो।

कृपया ध्यान दें कि const पर कोई प्रभाव नहीं पड़ता है। एक संदर्भ प्रकार पर लागू const चुपचाप अनदेखा किया जाता है। इसलिए यदि संकलक संदर्भ ढहने का समर्थन करता है, तो निम्नलिखित कानूनी नहीं है

int const x = 0; 

// illegal: trying to bind "int&" to "int const"! 
ref const& r = x; 
+0

ग्रेट, मुझे पता चला कि यह गुण कक्षाओं द्वारा हल किया जा सकता है, लेकिन मैंने कभी भी [एसटीएल के कार्यान्वयन] में ऐसी कोई चीज़ नहीं देखी है। –

+0

यह नहीं होना चाहिए "यानी एक 'टी'' जहां 'टी' संदर्भ प्रकार को इंगित करता है 'टी एंड' फिर से होता है? – fredoverflow

+0

@ फ्रेड जो स्वयं-पुनरावर्ती होगा। मेरा मतलब है, यदि 'टी'' यू 'है, और आप' टी ''कहते हैं, तो परिणाम का प्रकार' टी' है - i.e 'U &'। बेशक, यह रावल संदर्भों के साथ संगत नहीं है। मुझे यह कहना होगा कि "i.e a' T & 'जहां' टी' एक प्रकार को दर्शाता है 'U & -or - &&' प्रकार 'यू' 'को दर्शाता है, जो रावल्यू रेफ के साथ सही होगा। –

5

this के अनुसार, सी ++ 98 में संदर्भ टूट के लिए केवल सीमित समर्थन नहीं थी:

सी ++ 98 में, वहाँ केवल एक संदर्भ गिर नियम है: टी & & या एक संदर्भ एक संदर्भ के लिए, & टी यह संक्षिप्त हो:

void g(int & ri) {++ri;} // int& & -> int& 
void f(int & ri) {g(ri);} 

वहाँ भी, यह declar करने की कोशिश करने के लिए अवैध है ईए चर कि एक संदर्भ के लिए एक संदर्भ है:

int ben; 
int& bill(ben);  // OK 
int & & bob(bill); // error C2529: 'bob' : reference to reference is illegal 
+2

कोई संदर्भ नहीं है सी ++ 03। उस लेख के लेखक गुमराह है। किसी संदर्भ के नाम का उपयोग करके पहचान-अभिव्यक्ति का प्रकार संदर्भ प्रकार नहीं है। * नहीं * अभिव्यक्ति संदर्भ प्रकार है। अभिव्यक्तियों में मूल्य श्रेणियां होती हैं जो तय करती हैं कि वे संदर्भों से कैसे जुड़ सकते हैं। – Potatoswatter

+0

@Potatoswatter - धन्यवाद, और अब भी बेहतर संदर्भ हैं। मैं इस भाग को हटा दूंगा। –

+0

धन्यवाद ... लेकिन हम्म, वह लिंक वह नहीं है जिसे मैंने पहले किया था। – Potatoswatter

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