संदर्भ C ++ में "कॉन्स्टेबल" क्यों नहीं हैं?


86

हम जानते हैं कि "कॉन्स्टेबल वैरिएबल" इंगित करता है कि एक बार असाइन करने के बाद, आप वैरिएबल को इस तरह नहीं बदल सकते:

int const i = 1;
i = 2;

उपरोक्त कार्यक्रम संकलन में विफल रहेगा; एक त्रुटि के साथ संकेत देता है:

assignment of read-only variable 'i'

कोई समस्या नहीं, मैं इसे समझ सकता हूं, लेकिन निम्नलिखित उदाहरण मेरी समझ से परे है:

#include<iostream>
using namespace std;
int main()
{
    boolalpha(cout);
    int const i = 1;
    cout << is_const<decltype(i)>::value << endl;
    int const &ri = i;
    cout << is_const<decltype(ri)>::value << endl;
    return 0;
}

यह आउटपुट करता है

true
false

अजीब। हम जानते हैं कि एक बार एक संदर्भ एक नाम / चर के लिए बाध्य है, हम इस बंधन को नहीं बदल सकते हैं, हम इसकी बाध्य वस्तु को बदलते हैं। तो मुझे लगता है कि प्रकार के riसमान होना चाहिए i: जब iint const, क्यों riनहीं है const?


3
इसके अलावा, boolalpha(cout)बहुत ही असामान्य है। आप std::cout << boolalphaइसके बजाय कर सकते हैं ।
इसाना

6
इतना ri"उर्फ" अप्रभेद्य होने के लिए i
कज़

1
ऐसा इसलिए है क्योंकि एक संदर्भ हमेशा एक ही वस्तु से घिरा होता है। iएक संदर्भ भी है, लेकिन ऐतिहासिक कारणों से आप इसे स्पष्ट रूप में घोषित नहीं करते हैं। इस प्रकार iसंदर्भ है कि एक भंडारण को संदर्भित करता है और riएक संदर्भ है कि एक ही भंडारण को संदर्भित करता है। लेकिन बीच में i और प्रकृति में कोई अंतर नहीं है ri। जैसा कि आप किसी संदर्भ के बंधन को नहीं बदल सकते हैं, जैसा कि इसे अर्हता प्राप्त करने की कोई आवश्यकता नहीं है const। और मुझे यह दावा करने दें कि @Kaz टिप्पणी कहीं अधिक बेहतर है कि मान्य उत्तर (कभी भी पॉइंटर्स का उपयोग करते हुए संदर्भों की व्याख्या न करें, रेफ एक नाम है, एक ptr एक चर है)।
जीन-बैप्टिस्ट यूनेस

1
विलक्षण प्रश्न। इस उदाहरण को देखने से पहले, मुझे इस मामले में भी is_constवापसी की उम्मीद होगी true। मेरी राय में, यह constमूल रूप से पीछे की ओर क्यों है इसका एक अच्छा उदाहरण है ; एक "उत्परिवर्तित" विशेषता (एक ला रस्ट की mut) ऐसा लगता है कि यह अधिक सुसंगत होगा।
काइल स्ट्रैंड

1
शायद शीर्षक को "क्यों is_const<int const &>::valueझूठा है?" या इसी के समान; मैं प्रकार के लक्षणों के बारे में पूछने के अलावा किसी भी प्रश्न को देखने के लिए संघर्ष कर रहा हूं
एमएम

जवाबों:


52

यह काउंटर सहज ज्ञान युक्त लग सकता है लेकिन मुझे लगता है यह समझने के लिए जिस तरह से एहसास है कि, कुछ मामलों में है, संदर्भ इलाज कर रहे हैं वाक्य रचना की तरह संकेत दिए गए

यह सूचक के लिए तर्कसंगत लगता है :

int main()
{
    boolalpha(cout);

    int const i = 1;
    cout << is_const<decltype(i)>::value << endl;

    int const* ri = &i;
    cout << is_const<decltype(ri)>::value << endl;
}

आउटपुट:

true
false

यह तर्कसंगत है क्योंकि हम जानते हैं कि यह पॉइंटर ऑब्जेक्ट नहीं है जो कि कॉन्स्ट है (इसे कहीं और इंगित किया जा सकता है) यह वह ऑब्जेक्ट है जिसे इंगित किया जा रहा है।

इसलिए हम सही ढंग से पॉइंटर की स्थिरता को स्वयं देखते हैं ।false

अगर हम सूचक को खुद बनाना चाहते हैं तो हमें constकहना होगा:

int main()
{
    boolalpha(cout);

    int const i = 1;
    cout << is_const<decltype(i)>::value << endl;

    int const* const ri = &i;
    cout << is_const<decltype(ri)>::value << endl;
}

आउटपुट:

true
true

और इसलिए मुझे लगता है कि हम संदर्भ के साथ एक वाक्यविन्यास सादृश्य देखते हैं ।

हालाँकि संदर्भ विशेष रूप से एक महत्वपूर्ण सम्मान में संकेत करने के लिए अलग-अलग हैं , हमें एक बार बाध्य होने वाली किसी अन्य वस्तु के संदर्भ में विद्रोह करने की अनुमति नहीं है ।

इसलिए भले ही संदर्भ एक ही वाक्यविन्यास को साझा करते हैं क्योंकि संकेत अलग-अलग हैं और इसलिए भाषा हमें संदर्भ को constइस तरह घोषित करने से रोकती है :

int main()
{
    boolalpha(cout);

    int const i = 1;
    cout << is_const<decltype(i)>::value << endl;

    int const& const ri = i; // COMPILE TIME ERROR!
    cout << is_const<decltype(ri)>::value << endl;
}

मुझे लगता है कि हमें ऐसा करने की अनुमति नहीं है क्योंकि इसकी आवश्यकता तब नहीं पड़ती है जब भाषा के नियम संदर्भ को उसी तरह से रिबाउंड होने से रोकते हैं जिस तरह से एक पॉइंटर (यदि यह घोषित नहीं किया गया है const)।

तो सवाल का जवाब देने के लिए:

Q) C ++ में "संदर्भ" क्यों नहीं है?

आपके उदाहरण में वाक्य रचना constउसी तरह से संदर्भित की जा रही है जिस तरह से आप एक पॉइंटर की घोषणा कर रहे थे ।

सही या गलत तरीके से हमें स्वयं ही संदर्भ बनाने की अनुमति नहीं है constलेकिन अगर हम होते तो ऐसा ही होता:

int const& const ri = i; // not allowed

Q) हम जानते हैं कि एक बार एक संदर्भ एक नाम / चर के लिए बाध्य है, हम इस बंधन को नहीं बदल सकते हैं, हम इसकी बाइंड की गई वस्तु को बदलते हैं। तो मुझे लगता है कि प्रकार के riसमान होना चाहिए i: जब iint const, क्यों riनहीं है const?

रेफरीdecltype() को जिस वस्तु के लिए बाध्य किया जाता है, उसे स्थानांतरित क्यों नहीं किया जाता है?

मुझे लगता है कि यह संकेत के साथ अर्थ समतुल्यता के लिए है और शायद यह भी decltype()(घोषित प्रकार) का कार्य उस पर वापस देखना है जो बाध्यकारी होने से पहले घोषित किया गया था ।


13
ऐसा लगता है कि आप कह रहे हैं "संदर्भ कांस्ट नहीं हो सकता क्योंकि वे हमेशा कॉन्स्टेबल होते हैं"?
रुख

2
यह सच हो सकता है कि " शब्दबद्ध रूप से उन पर सभी कार्रवाइयाँ होने के बाद वे उस वस्तु पर स्थानांतरित हो जाते हैं जिसे वे संदर्भित करते हैं", लेकिन ओपी उम्मीद कर रहा था कि यह भी लागू होगा decltype, और पाया कि यह नहीं किया।
रुख

10
यहाँ संकेत करने वालों के लिए बहुत सारे भ्रामक दमन और संदिग्ध रूप से लागू उपमाएँ हैं, जो मुझे लगता है कि इस मुद्दे को आवश्यकता से अधिक भ्रमित करता है, जब मानक की जाँच की तरह sonyuanyao ने सीधे वास्तविक बिंदु पर प्राप्त किया: एक संदर्भ cv-qualifiable प्रकार नहीं है, इसलिए यह नहीं हो सकता const, इसलिए std::is_constवापस लौटना चाहिए false। वे इसके बजाय शब्दों का इस्तेमाल कर सकते थे जिसका मतलब था कि इसे वापस लौटना चाहिए true, लेकिन उन्होंने ऐसा नहीं किया। बस! संकेत के बारे में यह सब सामान, "मुझे लगता है", "मुझे लगता है", आदि किसी भी वास्तविक elucidation प्रदान नहीं करता है।
अंडरस्कोर_ड

1
@underscore_d यह टिप्पणी अनुभाग के लिए चैट के लिए शायद एक बेहतर प्रश्न है, लेकिन क्या आपके पास संदर्भों के बारे में सोचने के इस तरीके से "अनावश्यक भ्रम" का उदाहरण है? अगर उन्हें इस तरह से लागू किया जा सकता है, तो उन्हें इस तरह से सोचने में क्या परेशानी है? (मुझे नहीं लगता कि यह सवाल मायने रखता है क्योंकि decltypeरनटाइम ऑपरेशन नहीं है, इसलिए "रनटाइम पर, संदर्भ पॉइंटर्स की तरह व्यवहार करते हैं" विचार, सही है या नहीं, वास्तव में लागू नहीं होता है।
काइल स्ट्रैंड

1
संदर्भों का संकेत बिंदुओं की तरह वाक्यात्मक रूप से व्यवहार नहीं किया जाता है। उन्हें घोषित करने और उपयोग करने के लिए अलग-अलग वाक्यविन्यास हैं। तो मुझे भी यकीन नहीं है कि आपका क्या मतलब है।
जॉर्डन मेलो

55

"री" "कांस्ट" क्यों नहीं है?

std::is_const जाँचता है कि प्रकार कांस्टेबल योग्य है या नहीं।

यदि T एक कांस्टेबल-योग्य प्रकार है (जो कि, const, या const वाष्पशील है), तो सदस्य को निरंतर मूल्य समान सत्य प्रदान करता है। किसी अन्य प्रकार के लिए, मूल्य गलत है।

लेकिन संदर्भ कांस्टेबल योग्य नहीं हो सकता। सन्दर्भ [dcl.ref] / १

Cv- योग्य संदर्भ तब बनाए जाते हैं, सिवाय इसके कि जब cv-qualifiers टाइप-एफ-नेम ([dcl.typedef], [temp.param]] या डिक्लेपट-स्पेसियर ([dcl.type.simple]) के उपयोग के माध्यम से पेश किए जाते हैं जिस स्थिति में सीवी-क्वालीफायर को नजरअंदाज किया जाता है।

तो is_const<decltype(ri)>::valueवापस आ जाएगी false, क्योंकि ri(संदर्भ) एक स्थिरांक योग्य प्रकार नहीं है। जैसा कि आपने कहा, हम आरंभीकरण के बाद एक संदर्भ को अस्वीकार नहीं कर सकते हैं, जिसका अर्थ है कि संदर्भ हमेशा "कॉन्स्ट" होता है, दूसरी ओर, कॉन्स्टेबल-क्वालीफाइड रेफरेंस या कॉन्स्टल-अनक्लाइफाइड रेफरेंस वास्तव में समझ में नहीं आता है।


5
मानक के लिए सीधे और इसलिए सीधे स्वीकार किए गए उत्तर के सभी वेफलिंग के बजाय बिंदु पर सीधे।
अंडरस्कोर_ड

5
@underscore_d यह एक अच्छा जवाब है जब तक आप पहचान नहीं लेते कि ऑप भी क्यों पूछ रहा था। "क्योंकि यह ऐसा कहता है" प्रश्न के उस पहलू के लिए वास्तव में उपयोगी नहीं है।
साधारण जुआन

5
@ user9999999 दूसरा जवाब वास्तव में उस पहलू का जवाब नहीं देता है। यदि कोई संदर्भ पलटाव नहीं कर सकता है, तो is_constवापस क्यों नहीं आता है true? यह उत्तर इस बात का एक सादृश्य बनाने की कोशिश करता है कि कैसे बिंदु वैकल्पिक रूप से पुन: प्रयोज्य हैं, जबकि संदर्भ नहीं हैं - और ऐसा करने में, उसी कारण से आत्म-विरोधाभास होता है। मुझे यकीन नहीं है कि मानक लिखने वालों द्वारा कुछ हद तक मनमाने फैसले के अलावा, वास्तव में एक वास्तविक स्पष्टीकरण है, और कभी-कभी वह सबसे अच्छा है जिसकी हम उम्मीद कर सकते हैं। इसलिए यह जवाब।
अंडरस्कोर_ड

2
एक अन्य महत्वपूर्ण पहलू, मुझे लगता है, वह यह है कि decltypeहै एक समारोह नहीं है और इसलिए सीधे संदर्भ में ही पर काम करता है के बजाय वस्तु के लिए भेजा करने पर। (यह शायद "संदर्भ मूल रूप से संकेत देने वाले हैं" उत्तर के लिए अधिक प्रासंगिक है, लेकिन मुझे अभी भी लगता है कि यह इस उदाहरण को भ्रमित करने वाला है और इसलिए यहां ध्यान देने योग्य है।)
काइल स्ट्रैंड

3
@KyleStrand से टिप्पणी को आगे बढ़ाने के लिए: decltype(name)एक सामान्य से अलग कार्य करता है decltype(expr)। इसलिए, उदाहरण के लिए, decltype(i)घोषित प्रकार iहै const int, जबकि decltype((i))होगा int const &
डैनियल शेपलर

18

आपको std::remove_referenceवह मूल्य प्राप्त करने के लिए उपयोग करने की आवश्यकता है जिसे आप खोज रहे हैं।

std::cout << std::is_const<std::remove_reference<decltype(ri)>::type>::value << std::endl;

अधिक जानकारी के लिए, इस पोस्ट को देखें ।


7

मैक्रों क्यों नहीं हैं const? कार्य? शाब्दिक? प्रकारों के नाम?

const चीजें केवल अपरिवर्तनीय चीजों का एक सबसेट हैं।

चूँकि संदर्भ प्रकार सिर्फ constइतने ही हैं - प्रकार - हो सकता है कि यह उन सभी के लिए समरूपता की आवश्यकता के लिए कुछ समझ बनाये, जो अन्य प्रकार (विशेष रूप से पॉइंटर प्रकार के साथ) के लिए समरूपता के लिए है, लेकिन यह बहुत जल्दी थकाऊ होगा।

यदि C ++ में डिफ़ॉल्ट रूप से अपरिवर्तनीय वस्तुएं होती हैं , तो किसी mutableभी चीज पर कीवर्ड की आवश्यकता होती है, जो आप नहीं करना चाहते हैं const, तो यह आसान होता: केवल प्रोग्रामर mutableको संदर्भ प्रकारों में जोड़ने की अनुमति न दें ।

जैसा कि है, वे योग्यता के बिना अपरिवर्तनीय हैं।

और, चूंकि वे constअयोग्य नहीं हैं , इसलिए यह शायद एक प्रकार के संदर्भ के लिए अधिक भ्रामक होगा क्योंकि यह is_constसच है।

मुझे यह एक उचित समझौता लगता है, खासकर जब से अपरिवर्तनीयता वैसे भी केवल इस तथ्य से लागू होती है कि कोई वाक्यविन्यास किसी संदर्भ को बदलने के लिए मौजूद नहीं है।


5

यह C ++ में क्विकर / फीचर है। यद्यपि हम संदर्भों के प्रकारों के बारे में नहीं सोचते हैं, वे वास्तव में प्रकार प्रणाली में "बैठते हैं"। हालांकि यह अजीब लगता है (यह देखते हुए कि जब संदर्भ का उपयोग किया जाता है, तो संदर्भ शब्दार्थ स्वचालित रूप से होता है और संदर्भ "रास्ते से बाहर हो जाता है"), कुछ बचाव योग्य कारण हैं कि संदर्भों को एक अलग विशेषता के रूप में सिस्टम में टाइप करने के बजाय एक अलग विशेषता के रूप में क्यों बनाया गया है? प्रकार।

सबसे पहले, आइए विचार करें कि घोषित नाम की प्रत्येक विशेषता प्रकार प्रणाली में नहीं होनी चाहिए। सी भाषा से, हमारे पास "भंडारण वर्ग", और "लिंकेज" है। एक नाम के रूप में पेश किया जा सकता है extern const int ri, जहां externस्थिर भंडारण वर्ग और लिंकेज की उपस्थिति को इंगित करता है। प्रकार बस है const int

C ++ स्पष्ट रूप से इस धारणा को स्वीकार करता है कि अभिव्यक्तियों में ऐसी विशेषताएँ हैं जो टाइप सिस्टम के बाहर हैं। भाषा में अब "मूल्य वर्ग" की अवधारणा है जो गैर-प्रकार की विशेषताओं की बढ़ती संख्या को व्यवस्थित करने का एक प्रयास है जो एक अभिव्यक्ति का प्रदर्शन कर सकती है।

फिर भी संदर्भ प्रकार हैं। क्यों?

यह सी ++ ट्यूटोरियल ऐसे ही एक घोषणा में समझाया जा करने के लिए इस्तेमाल const int &riकी शुरुआत की riप्रकार होने के रूप में const intहै, लेकिन संदर्भ अर्थ विज्ञान। वह संदर्भ शब्दार्थ एक प्रकार का नहीं था; यह केवल नाम और भंडारण स्थान के बीच एक असामान्य संबंध का संकेत देने वाला एक प्रकार का गुण था। इसके अलावा, यह तथ्य कि संदर्भ प्रकार नहीं हैं, का उपयोग इस बात को तर्कसंगत बनाने के लिए किया गया था कि आप संदर्भों के आधार पर प्रकारों का निर्माण क्यों नहीं कर सकते हैं, भले ही प्रकार निर्माण वाक्यविन्यास इसकी अनुमति देता हो। उदाहरण के लिए, सरणियों या बिंदुओं के संदर्भ में संभव नहीं होने के लिए: const int &ari[5]और const int &*pri

लेकिन वास्तव में संदर्भ हैं प्रकार के और इतने decltype(ri)कुछ संदर्भ प्रकार नोड जो अयोग्य है प्राप्त करता है। इस प्रकार के पेड़ के साथ अंतर्निहित प्रकार प्राप्त करने के लिए आपको इस नोड को पिछले हिस्से में उतरना होगा remove_reference

जब आप उपयोग करते हैं ri, तो संदर्भ पारदर्शी रूप से हल हो जाता है, ताकि ri"जैसा दिखता है और जैसा महसूस होता है i" और इसे इसके लिए "उपनाम" कहा जा सके। प्रकार प्रणाली में, हालांकि, riवास्तव में एक प्रकार है जो " संदर्भ const int " है।

संदर्भ प्रकार क्यों हैं?

विचार करें कि यदि संदर्भ प्रकार नहीं थे , तो इन कार्यों को एक ही प्रकार माना जाएगा:

void foo(int);
void foo(int &);

यह केवल उन कारणों के लिए नहीं हो सकता है जो बहुत अधिक स्पष्ट हैं। यदि उनके पास एक ही प्रकार होता है, तो इसका मतलब है कि या तो घोषणा या तो परिभाषा के लिए उपयुक्त होगी, और इसलिए प्रत्येक (int)फ़ंक्शन को एक संदर्भ लेने के लिए संदेह करना होगा।

इसी प्रकार, यदि संदर्भ प्रकार नहीं थे, तो ये दो श्रेणी की घोषणाएं समान होंगी:

class foo {
  int m;
};

class foo {
  int &m;
};

एक घोषणा इकाई के लिए एक घोषणा का उपयोग करना सही होगा, और दूसरी घोषणा का उपयोग करने के लिए उसी कार्यक्रम में एक और अनुवाद इकाई।

तथ्य यह है कि एक संदर्भ के कार्यान्वयन में अंतर होता है और इसे उस प्रकार से अलग करना असंभव है, क्योंकि C ++ में टाइप को एक इकाई के कार्यान्वयन के साथ करना है: बोलने के लिए बिट्स में इसका "लेआउट"। यदि दो फ़ंक्शन एक ही प्रकार के हैं, तो उन्हें एक ही बाइनरी कॉलिंग सम्मेलनों के साथ लागू किया जा सकता है: एबीआई एक ही है। यदि दो संरचनाओं या वर्गों में एक ही प्रकार है, तो उनका लेआउट समान है और साथ ही सभी सदस्यों तक पहुंच के शब्दार्थ भी हैं। संदर्भों की उपस्थिति प्रकार के इन पहलुओं को बदल देती है, और इसलिए यह उन्हें सीधे प्रकार के सिस्टम में शामिल करने का एक सीधा डिजाइन निर्णय है। (हालांकि, यहां एक प्रतिवाद पर ध्यान दें: एक संरचना / वर्ग का सदस्य हो सकता है static, जो प्रतिनिधित्व को भी बदलता है; फिर भी वह प्रकार नहीं है।)

इस प्रकार, संदर्भ प्रकार में हैं प्रणाली "द्वितीय श्रेणी के नागरिक" (आईएसओ सी में कार्यों और सरणियों के विपरीत नहीं)। कुछ ऐसी चीजें हैं जो हम संदर्भों के साथ "नहीं" कर सकते हैं, जैसे कि संदर्भकर्ताओं को संदर्भों की घोषणा करना, या उनमें से सरणियाँ। लेकिन इसका मतलब यह नहीं है कि वे टाइप नहीं हैं। वे सिर्फ एक तरह से टाइप नहीं हैं कि यह समझ में आता है।

ये सभी द्वितीय श्रेणी-प्रतिबंध आवश्यक नहीं हैं। यह देखते हुए कि संदर्भों की संरचनाएं हैं, संदर्भों की सरणियाँ हो सकती हैं! उदाहरण के लिए

// fantasy syntax
int x = 0, y = 0;
int &ar[2] = { x, y };

// ar[0] is now an alias for x: could be useful!

यह सिर्फ C ++ में लागू नहीं है, बस इतना ही। संदर्भ के लिए संकेत बिल्कुल भी समझ में नहीं आते हैं, क्योंकि एक संदर्भ से उठाया गया एक संकेतक सिर्फ संदर्भित वस्तु पर जाता है। संदर्भों की कोई सरणियाँ नहीं होने का संभावित कारण यह है कि सी ++ लोग एरे को सी से विरासत में मिली एक प्रकार की निम्न-स्तरीय विशेषता मानते हैं, जो कई प्रकार से टूटी हुई है जो अपूरणीय है, और वे एरेज़ को स्पर्श नहीं करना चाहते हैं। कुछ भी नया करने का आधार। संदर्भों के सरणियों का अस्तित्व, हालांकि, इस बात का स्पष्ट उदाहरण देगा कि संदर्भों को किस प्रकार का होना चाहिए।

गैर- constपरिवर्तनीय प्रकार: आईएसओ C90 में भी पाया जाता है!

कुछ जवाब इस तथ्य पर इशारा कर रहे हैं कि संदर्भ एक constक्वालीफायर नहीं लेते हैं । यह बल्कि एक लाल हेरिंग है, क्योंकि घोषणा const int &ri = iभी एक अयोग्य संदर्भ बनाने का प्रयास नहीं कर रही है const: यह एक कास्ट-योग्य प्रकार (जो स्वयं नहीं है const) का संदर्भ है । जैसे const in *riकिसी चीज को पॉइंटर घोषित करता है const, लेकिन वह पॉइंटर खुद नहीं है const

यह कहा, यह सच है कि संदर्भ constखुद को क्वालीफायर नहीं ले जा सकते हैं।

फिर भी, यह इतना विचित्र नहीं है। यहां तक ​​कि आईएसओ सी 90 भाषा में, सभी प्रकार नहीं हो सकते हैं const। अर्थात्, सरणियाँ नहीं हो सकतीं।

सबसे पहले, सिंटैक्स एक कॉन्स्टेंट ऐरे को घोषित करने के लिए मौजूद नहीं है: int a const [42]गलत है।

हालांकि, उपरोक्त घोषणा क्या करने की कोशिश कर रही है एक मध्यवर्ती के माध्यम से व्यक्त किया जा सकता है typedef:

typedef int array_t[42];
const array_t a;

लेकिन यह ऐसा नहीं करता जैसा दिखता है। इस घोषणा में, यह नहीं है aजो हो जाता है constयोग्य है, लेकिन तत्वों! यह कहना है, a[0]एक है const int, लेकिन aसिर्फ "int की सरणी" है। नतीजतन, इसके लिए निदान की आवश्यकता नहीं है:

int *p = a; /* surprise! */

यह करता है:

a[0] = 1;

फिर, यह इस विचार को रेखांकित करता है कि संदर्भ कुछ प्रकार से "द्वितीय श्रेणी" में हैं, जैसे कि सरणियाँ।

ध्यान दें कि अनुरूप कैसे अधिक गहराई से पकड़ता है, क्योंकि सरणियों में भी एक "अदृश्य रूपांतरण व्यवहार" होता है, जैसे संदर्भ। प्रोग्रामर के बिना किसी भी स्पष्ट ऑपरेटर का उपयोग करने के लिए, पहचानकर्ता aस्वचालित रूप से एक int *सूचक में बदल जाता है , जैसे कि अभिव्यक्ति &a[0]का उपयोग किया गया था। यह कैसे एक संदर्भ के अनुरूप है ri, जब हम इसे एक प्राथमिक अभिव्यक्ति के रूप में उपयोग करते हैं, तो जादुई रूप से उस वस्तु iको दर्शाता है जिसके लिए वह बाध्य है। यह "सरणी से सूचक क्षय" की तरह एक और "क्षय" है।

और जैसे हम "सरणी से पॉइंटर" के क्षय को गलत तरीके से सोचने में भ्रमित नहीं होना चाहिए कि "सरणियां सी और सी ++ में सिर्फ संकेत हैं", वैसे ही हमें यह नहीं सोचना चाहिए कि संदर्भ केवल उपनाम हैं जिनका अपना कोई प्रकार नहीं है।

जब decltype(ri)संदर्भ के सामान्य रूपांतरण को उसके संदर्भ वस्तु में sizeof aदबा दिया जाता है, तो यह सरणी-से-पॉइंटर रूपांतरण को दबाने से अलग नहीं होता है , और इसके आकार की गणना करने के लिए सरणी प्रकार पर ही काम करता है ।


आपको यहां बहुत सारी रोचक और उपयोगी जानकारी मिली है (+1), लेकिन यह कमोबेश इस तथ्य तक सीमित है कि "संदर्भ प्रकार प्रणाली में हैं" - यह पूरी तरह से ओपी के सवाल का जवाब नहीं देता है। इस जवाब और @ songyuanyao के उत्तर के बीच, मैं कहूंगा कि स्थिति को समझने के लिए पर्याप्त जानकारी से अधिक है, लेकिन यह एक पूर्ण उत्तर के बजाय एक उत्तर के लिए आवश्यक पृष्ठभूमि की तरह लगता है ।
काइल स्ट्रैंड

1
इसके अलावा, मुझे लगता है कि यह वाक्य ध्यान देने योग्य है: "जब आप री का उपयोग करते हैं, तो संदर्भ पारदर्शी रूप से हल हो जाता है ..." एक प्रमुख बिंदु (जो मैंने टिप्पणियों में उल्लेख किया है, लेकिन जो अब तक किसी भी उत्तर में नहीं दिखा है। ) यह है कि यह पारदर्शी रिज़ॉल्यूशन decltype नहीं करता है (यह एक फ़ंक्शन नहीं है, इसलिए riआपके द्वारा वर्णित अर्थ में "उपयोग नहीं किया जाता है")। पर अपने पूरे ध्यान के साथ बहुत अच्छी तरह से में यह फिट प्रकार प्रणाली - वे कुंजी कनेक्शन है decltypeहै एक प्रकार-प्रणाली आपरेशन
काइल स्ट्रैंड

हम्म, सरणियों के बारे में सामान एक स्पर्शरेखा की तरह लगता है, लेकिन अंतिम वाक्य सहायक है।
काइल स्ट्रैंड

..... हालांकि इस बिंदु पर मैंने आपको पहले ही उखाड़ दिया है और मैं ओपी नहीं हूं, इसलिए आप मेरी आलोचनाओं को सुनकर वास्तव में कुछ हासिल नहीं कर रहे हैं या हार रहे हैं ....
काइल स्ट्रैंड

जाहिर है कि एक आसान (और सही उत्तर) हमें मानक की ओर इशारा करता है, लेकिन मुझे यहां पृष्ठभूमि की सोच पसंद है, हालांकि कुछ लोग यह तर्क दे सकते हैं कि इसके कुछ हिस्सों में दम है। +1।
स्टीव किड

-5

const x & x ”का अर्थ है x उपनाम X वस्तु। लेकिन आप x के माध्यम से उस X ऑब्जेक्ट को बदल नहीं सकते।

और std :: is_const देखें ।


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