संदर्भों की सरणियाँ अवैध क्यों हैं?


149

निम्न कोड संकलित नहीं करता है।

int a = 1, b = 2, c = 3;
int& arr[] = {a,b,c,8};

इस बारे में सी ++ मानक क्या कहता है?

मुझे पता है कि मैं एक वर्ग घोषित कर सकता हूं जिसमें एक संदर्भ होता है, फिर उस वर्ग की एक सरणी बनाएं, जैसा कि नीचे दिखाया गया है। लेकिन मैं वास्तव में जानना चाहता हूं कि उपरोक्त कोड क्यों संकलित नहीं करता है।

struct cintref
{
    cintref(const int & ref) : ref(ref) {}
    operator const int &() { return ref; }
private:
    const int & ref;
    void operator=(const cintref &);
};

int main() 
{
  int a=1,b=2,c=3;
  //typedef const int &  cintref;
  cintref arr[] = {a,b,c,8};
}

संदर्भों की एक सरणी का अनुकरण करने के struct cintrefबजाय इसका उपयोग करना संभव है const int &


1
यहां तक ​​कि अगर सरणी वैध थी, तो उसमें एक कच्चे '8' मान रखने से काम नहीं चलेगा। यदि आपने "intlink value = 8;" किया है, तो यह बुरी तरह से मर जाएगा, क्योंकि यह बहुत "बस int & value = 8;" में अनुवादित है। एक संदर्भ को एक चर का संदर्भ देना चाहिए।
ग्रांट पीटर्स

3
intlink value = 8;काम करेगा। अगर आपको विश्वास नहीं है तो जाँच करें।
एलेक्सी मालिस्टोव जू

7
जैसा कि एलेक्सी बताते हैं, एक संदर्भ के लिए एक प्रतिद्वंद्विता को बांधने के लिए यह पूरी तरह से वैध है।
अवकर

1
क्या नहीं है कि काम है operator=। संदर्भों को फिर से नहीं भेजा जा सकता है। क्या तुम सच में इस तरह के अर्थ विज्ञान चाहते हैं - हालांकि मैं व्यक्तिगत रूप से एक स्थिति है जिसमें वे व्यावहारिक रूप से उपयोगी हो नहीं पाया है - तो std::reference_wrapper, जिस तरह से यह करने के लिए किया जाएगा के रूप में यह वास्तव में एक सूचक को संग्रहीत करता है लेकिन प्रदान करता है संदर्भ की तरह operatorहै और करता reseating अनुमति देते हैं। लेकिन तब मैं सिर्फ एक पॉइंटर का उपयोग करूँगा!
अंडरस्कोर_ड

1
ऑपरेटर = निजी है और कार्यान्वित नहीं है, उर्फ ​​C ++ 11 में क्या है = हटाएं।
जिमी हर्ट्जेल

जवाबों:


148

मानक के बारे में आपके प्रश्न का उत्तर देते हुए मैं C ++ मानक the8.3.2 / 4 का हवाला दे सकता हूं :

संदर्भों का कोई संदर्भ नहीं होगा, संदर्भों की कोई सारणी और संदर्भों के लिए कोई संकेत नहीं होगा।


32
कहने के लिए और क्या है?
बहुवचन

9
वहाँ एक ही कारण के लिए संदर्भों के सरणियों होना चाहिए हम संकेत के arrays, एक ही जानकारी है, लेकिन अलग हैंडलिंग, नहीं?
नीयू- rah

6
यदि संकलक डेवलपर्स ने संदर्भ के सरणियों को अनुमति देने के लिए एक विस्तार के रूप में निर्णय लिया, तो क्या यह एक सफलता होगी? या फिर कुछ वास्तविक समस्याएं हैं - शायद अस्पष्ट कोड - जो इस विस्तार को परिभाषित करने के लिए इसे बहुत भ्रामक बना देगा?
हारून मैकडैड

23
@AaronMcDaid मुझे लगता है कि असली कारण - जो इस और इसी तरह की चर्चाओं से बहुत ही गैरहाजिर है - अगर किसी के पास संदर्भों की एक सरणी थी, तो एक तत्व के पते और उसके संदर्भ के पते के बीच कोई संभवतः कैसे विमुख होगा? 'आप किसी सरणी / कंटेनर / जो भी हो' में एक संदर्भ नहीं डाल सकते हैं, इस पर आपत्ति जताई जा सकती है, structजिसका एकमात्र सदस्य एक संदर्भ है। लेकिन, ऐसा करने से, अब आपको नाम के लिए संदर्भ और मूल ऑब्जेक्ट दोनों मिल गए हैं ... जिसका अर्थ है कि अब आप स्पष्ट रूप से उस स्थिति को बता सकते हैं जिसे आप चाहते हैं। स्पष्ट लगता है ... तो किसी ने क्यों नहीं कहा?
अंडरस्कोर_ड

95
@ पॉलीग्लॉट What more is there to say?एक तर्क क्यों ? मैं सभी मानक के बारे में हूँ, लेकिन इसका हवाला देते हुए और यह मानते हुए कि चर्चा का अंत उपयोगकर्ताओं की आलोचनात्मक सोच को नष्ट करने के लिए एक निश्चित-आग के रास्ते की तरह लगता है - साथ ही भाषा को विकसित करने की किसी भी क्षमता के साथ, जैसे कि चूक की सीमाओं से परे या कृत्रिम प्रतिबंध। बहुत अधिक है 'क्योंकि मानक' यहाँ - और पर्याप्त नहीं 'कहता है और यह कहना बहुत ही समझदारी की बात है, निम्न व्यावहारिक कारणों से।' मुझे नहीं पता कि उत्कर्ष उत्तर की ओर इतनी उत्सुकता से क्यों बहते हैं कि केवल पूर्व को कहें बिना उत्तरार्द्ध का पता लगाने की कोशिश किए बिना।
अंडरस्कोर_ड

64

संदर्भ वस्तु नहीं हैं। उनके पास स्वयं का भंडारण नहीं है, वे केवल मौजूदा वस्तुओं का संदर्भ देते हैं। इस कारण से इसका संदर्भों के सरणियों से कोई मतलब नहीं है।

यदि आप एक लाइट-वेट ऑब्जेक्ट चाहते हैं जो किसी अन्य ऑब्जेक्ट को संदर्भित करता है तो आप एक पॉइंटर का उपयोग कर सकते हैं। structयदि आप सभी संदर्भों के लिए सभी संदर्भ सदस्यों के लिए स्पष्ट आरंभीकरण प्रदान करते हैं, तो आप केवल सरणियों में वस्तुओं के रूप में एक संदर्भ सदस्य के साथ उपयोग कर पाएंगे struct। संदर्भों को डिफ़ॉल्ट रूप से निष्क्रिय नहीं किया जा सकता है।

संपादित करें: जिया 3 नोट के रूप में, घोषणाओं के मानक खंड में संदर्भों के सरणियों पर एक स्पष्ट निषेध है।


6
उनके स्वभाव में निरंतर बिंदुओं के रूप में संदर्भ समान हैं, और इसलिए वे कुछ को इंगित करने के लिए कुछ मेमोरी (भंडारण) लेते हैं।
इनजारुक

7
जरूरी नहीं है। संकलक पते को संग्रहीत करने से बचने में सक्षम हो सकता है, अगर यह उदाहरण के लिए स्थानीय ऑब्जेक्ट का संदर्भ है।
ईफ्रैम

4
जरुरी नहीं। संरचनाओं में संदर्भ आमतौर पर कुछ भंडारण लेते हैं। स्थानीय संदर्भ अक्सर नहीं। किसी भी तरह से, सख्त मानक अर्थों में, संदर्भ वस्तु नहीं हैं और (यह मेरे लिए नया था) नामित संदर्भ वास्तव में चर नहीं हैं ।
CB Bailey

26
हां, लेकिन यह एक कार्यान्वयन विवरण है। C ++ मॉडल का एक ऑब्जेक्ट स्टोरेज का एक टाइप किया हुआ क्षेत्र है। एक संदर्भ स्पष्ट रूप से एक वस्तु नहीं है और इसमें कोई गारंटी नहीं है कि यह किसी विशेष संदर्भ में भंडारण लेता है।
CB Bailey

9
इसे इस तरह से रखें: आपके पास foo करने के लिए 16 रेफरी के अलावा कुछ नहीं हो सकता है, और इसे बिल्कुल उसी तरह से उपयोग करें जैसे मैं अपने एएफएस सरणी का उपयोग करना चाहता हूं - सिवाय इसके कि आप 16 फू संदर्भों में अनुक्रमित नहीं कर सकते। । यह एक भाषा मस्सा IMHO है।
greggo

28

यह एक दिलचस्प चर्चा है। स्पष्ट रूप से रेफ की सरणियाँ एक समान रूप से अवैध हैं, लेकिन IMHO का कारण इतना सरल नहीं है क्योंकि यह कहना कि वे 'ऑब्जेक्ट नहीं हैं' या 'उनका कोई आकार नहीं है'। मैं बताता हूँ कि सरणियाँ स्वयं C / C ++ में पूर्ण-पूर्ण ऑब्जेक्ट नहीं हैं - यदि आप उस पर आपत्ति करते हैं, तो एक 'क्लास' टेम्प्लेट पैरामीटर के रूप में एक सरणी का उपयोग करके कुछ stl टेम्पलेट क्लासेस को तत्काल आज़माएँ, और देखें कि क्या होता है। आप उन्हें वापस नहीं कर सकते, उन्हें असाइन कर सकते हैं, उन्हें मापदंडों के रूप में पास कर सकते हैं। (एक सरणी परम एक सूचक के रूप में माना जाता है)। लेकिन एरे के एरे बनाना कानूनी है। सन्दर्भों में एक आकार होता है जिसे कंपाइलर गणना कर सकता है और आपको एक संदर्भ में आकार नहीं दे सकता है (लेकिन आप संदर्भ के अलावा कुछ भी नहीं बना सकते हैं। इसमें सभी बिंदुओं को समाहित करने के लिए पर्याप्त आकार होगा जो संदर्भों को लागू करते हैं। आप ऐसा कर सकते हैं'

struct mys {
 int & a;
 int & b;
 int & c;
};
...
int ivar1, ivar2, arr[200];
mys my_refs = { ivar1, ivar2, arr[12] };

my_refs.a += 3  ;  // add 3 to ivar1

वास्तव में आप इस लाइन को संरचनात्मक परिभाषा में जोड़ सकते हैं

struct mys {
 ...
 int & operator[]( int i ) { return i==0?a : i==1? b : c; }
};

... और अब मेरे पास कुछ है जो रेफरी की एक सरणी की तरह बहुत कुछ दिखता है:

int ivar1, ivar2, arr[200];
mys my_refs = { ivar1, ivar2, arr[12] };

my_refs[1] = my_refs[2]  ;  // copy arr[12] to ivar2
&my_refs[0];               // gives &my_refs.a == &ivar1

अब, यह एक वास्तविक सरणी नहीं है, यह एक ऑपरेटर अधिभार है; यह उन चीजों को नहीं करेगा जो आम तौर पर आकार के लिए करते हैं (उदाहरण के लिए) / आकार (गिरफ्तारी [0]), उदाहरण के लिए। लेकिन यह बिल्कुल वैसा ही है जैसा मैं चाहता हूं कि संदर्भों की एक सरणी, पूरी तरह से कानूनी सी ++ के साथ। सिवाय (ए) यह 3 या 4 से अधिक तत्वों के लिए सेट करने के लिए एक दर्द है, और (बी) यह एक गुच्छा का उपयोग करके एक गणना कर रहा है ?: जो कि अनुक्रमण का उपयोग करके किया जा सकता है (सामान्य सी-पॉइंटर-गणना-शब्दार्थ इंडेक्सिंग के साथ नहीं) , लेकिन फिर भी अनुक्रमण)। मैं एक बहुत ही सीमित 'एरे ऑफ रेफरेंस' प्रकार देखना चाहता हूं जो वास्तव में ऐसा कर सकता है। यानी संदर्भों की एक सरणी को सामान्य चीजों के रूप में नहीं माना जाएगा जो संदर्भ हैं, बल्कि यह एक नया 'सरणी-संदर्भ' होगा टेम्पलेट्स के साथ बनाते हैं)।

यह संभवतः काम करेगा, यदि आप इस तरह के बुरा नहीं मानते हैं: * * इस 'को int की एक सरणी के रूप में पुनरावृत्ति करें "और एक से बना एक संदर्भ लौटाएं: (अनुशंसित नहीं है, लेकिन यह दिखाता है कि कैसे उचित' सरणी ' काम करेगा):

 int & operator[]( int i ) { return *(reinterpret_cast<int**>(this)[i]); }

1
आप इसे C ++ 11 में कर सकते हैं std::tuple<int&,int&,int&> abcref = std::tie( a,b,c)- जो संदर्भों की एक "सरणी" बनाता है जिसे केवल std :: get का उपयोग करके संकलन-समय स्थिरांक द्वारा अनुक्रमित किया जा सकता है। लेकिन आप ऐसा नहीं कर सकते std::array<int&,3> abcrefarr = std::tie( a,b,c)। शायद ऐसा करने का एक तरीका है जो मुझे नहीं पता है। यह मुझे लगता है कि ऐसा करने का एक तरीका लिखना चाहिए, std::array<T&,N>जो यह कर सकता है - और इस प्रकार एक फ़ंक्शन std::tiearray(...)जो एक ऐसे लौटाता है (या std::array<T&,N>पता
भेजने

आपका प्रस्ताव मूर्खतापूर्ण है (IMO), और आपकी अंतिम पंक्ति मानती है कि एक संकेतक एक पॉइंटर पकड़ सकता है (आमतौर पर गलत, कम से कम जहां वह काम करता है)। लेकिन यहाँ केवल एक ही तर्क के साथ जवाब दिया गया है कि संदर्भों के सरणियों के लिए मना क्यों किया जाता है, इसलिए +1
निमो

@ नीमो यह वास्तव में एक प्रस्ताव के रूप में अभिप्रेत नहीं था, लेकिन केवल यह स्पष्ट करने के लिए कि इस तरह की चीज़ की कार्यक्षमता उसके चेहरे पर बेतुकी नहीं है। मैं अपनी अंतिम टिप्पणी में ध्यान देता हूं कि c ++ में वे चीजें हैं जो करीब आती हैं। इसके अलावा, अंतिम पंक्ति जिसे आप मानते हैं कि मेमोरी को इंट के संदर्भ में लागू करना उपयोगी रूप से एक पॉइंटर-टू-इंट के रूप में उतारा जा सकता है - संरचना में संदर्भ शामिल हैं, न कि स्याही - और यह सच हो जाता है। मैं यह दावा नहीं कर रहा कि यह पोर्टेबल है (या 'अपरिभाषित व्यवहार' नियमों से भी सुरक्षित है)। यह स्पष्ट करने के लिए था कि कैसे अनुक्रमण को अंडर-हुड के लिए इस्तेमाल किया जा सकता है ताकि सभी से बचने के लिए?:
greggo

काफी उचित। लेकिन मुझे लगता है कि यह विचार "उसके चेहरे पर बेतुका" है, और यही कारण है कि संदर्भों के सरणियों को अस्वीकार कर दिया गया है। एक सरणी, पहला और सबसे महत्वपूर्ण, एक कंटेनर है। सभी कंटेनरों को लागू करने के लिए मानक एल्गोरिदम के लिए एक पुनरावृत्ति प्रकार की आवश्यकता होती है। "T की सरणी" के लिए पुनरावृत्त प्रकार सामान्य रूप से "T *" है। संदर्भों की एक सरणी के लिए पुनरावृत्त प्रकार क्या होगा? इन सभी मुद्दों से निपटने के लिए भाषा की हैकिंग की मात्रा अनिवार्य रूप से बेकार सुविधा के लिए हास्यास्पद है। वास्तव में शायद मैं इसे अपने खुद के जवाब
निमो

@ नीमो यह मूल भाषा का हिस्सा होने की आवश्यकता नहीं है, इसलिए इट्रेटर प्रकार 'कस्टम' होना कोई बड़ी बात नहीं है। सभी विभिन्न कंटेनर प्रकारों में उनके पुनरावृत्त प्रकार होते हैं। इस मामले में, इटेरेटर, dereferenced, लक्ष्य objs को संदर्भित करेगा, सरणी में रेफ्स नहीं, जो कि सरणी के व्यवहार के साथ पूरी तरह से संगत है। इसे अभी भी टेम्पलेट के रूप में समर्थन करने के लिए नए C ++ व्यवहार की थोड़ी आवश्यकता हो सकती है std::array<T,N>, बहुत ही सरल , आसानी से ऐप कोड में परिभाषित किया गया, एसटीडी में जोड़ा नहीं गया :: c ++ 11 तक, संभवत: क्योंकि यह इस तरह से बिना किसी के साथ होने के लिए मस्सा है क्या = {1,2,3};वह 'भाषा हैकिंग' थी?
ग्राग्गो

28

अपने संपादन में टिप्पणी करें:

बेहतर समाधान है std::reference_wrapper

विवरण: http://www.cplusplus.com/reference/functional/reference_wrapper/

उदाहरण:

#include <iostream>
#include <functional>
using namespace std;

int main() {
    int a=1,b=2,c=3,d=4;
    using intlink = std::reference_wrapper<int>;
    intlink arr[] = {a,b,c,d};
    return 0;
}

नमस्ते यह वापस 09 में कहा गया था। नए पदों के लिए टिप देखो :)
22

9
पोस्ट पुरानी है लेकिन सभी को रेफरेंस_वॉपर के साथ समाधान के बारे में नहीं पता है। लोगों को C ++ 11 के STL और STDlib के बारे में पढ़ने की जरूरत है।
युवती

यह केवल कक्षा के नाम का उल्लेख करने के बजाय एक लिंक और नमूना कोड देता है reference_wrapper
डेविड स्टोन

12

एक सरणी एक सूचक के लिए स्पष्ट रूप से परिवर्तनीय है, और सूचक-टू-संदर्भ सी ++ में अवैध है


11
यह सच है कि आपके पास एक संदर्भ के लिए एक संकेतक नहीं हो सकता है, लेकिन यह कारण नहीं है कि आपके पास संदर्भों की एक सरणी नहीं हो सकती है। बल्कि वे दोनों इस तथ्य के लक्षण हैं कि संदर्भ वस्तु नहीं हैं।
रिचर्ड कॉर्डन

1
एक संरचना में संदर्भों के अलावा कुछ भी नहीं हो सकता है, और इसका आकार उनकी संख्या के अनुपात में होगा। यदि आपके पास Refs 'arr' का एक सरणी है, तो सामान्य सरणी-से-पॉइंटर रूपांतरण का कोई मतलब नहीं होगा, क्योंकि 'पॉइंटर-टू-रेफरेंस' का कोई मतलब नहीं है। लेकिन यह सिर्फ गिरफ्तारी [i] का उपयोग करने के लिए समझ में आता है, उसी तरह जैसे कि st.ref जब 'st' एक रेफरी वाली संरचना हो। हम्म। लेकिन और गिरफ्तार [0] पहले संदर्भित ऑब्जेक्ट का पता देगा, और गिरफ्तार [1] - और गिरफ्तार [0] के रूप में और गिरफ्तार नहीं किया जाएगा [2] - और गिरफ्तार [1] - यह बहुत विचित्रता पैदा करेगा।
ग्रैग्गो

11

दिया int& arr[] = {a,b,c,8};, क्या है sizeof(*arr)?

हर जगह, एक संदर्भ को केवल बात के रूप में माना जाता है, इसलिए sizeof(*arr)बस होना चाहिए sizeof(int)। लेकिन यह इस सरणी पर सरणी पॉइंटर अंकगणित को गलत बना देगा (यह मानते हुए कि संदर्भ समान चौड़ाई नहीं हैं)। अस्पष्टता को खत्म करने के लिए, यह निषिद्ध है।


हां। जब तक इसका आकार नहीं होता तब तक आपके पास किसी चीज़ की एक सरणी नहीं हो सकती। एक संदर्भ का आकार क्या है?
डेविड श्वार्ट्ज

4
@DavidSchwartz structकिसका एकमात्र सदस्य है वह संदर्भ और पता करें ..?
अंडरस्कोर_ड

3
यह स्वीकृत उत्तर होना चाहिए, न कि मूर्खतापूर्ण पांडित्य जो केवल ओपी में मानक फेंकता है।
टायसन जैकब्स

शायद कोई टाइपो हो। "यह मानते हुए कि संदर्भ समान चौड़ाई नहीं हैं, तो यह होना चाहिए" यह मानते हुए कि संदर्भों की चौड़ाई के समान चौड़ाई नहीं हैं "। बदलें है करने के लिए के रूप में
ज़िंगोगोली

लेकिन रुकिए, इस तर्क से आपके पास संदर्भ सदस्य चर नहीं हो सकते।
टायसन जैकब्स

10

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

बूस्ट का उपयोग करें :: reference_wrapper, या बढ़ावा :: टपल को इसके बजाय; या सिर्फ संकेत।


5

मेरा मानना ​​है कि उत्तर बहुत सरल है और इसका संदर्भों के शब्दार्थ नियमों के साथ क्या करना है और कैसे सी + + में एरे को संभाला जाता है।

संक्षेप में: संदर्भों को उन संरचनाओं के रूप में सोचा जा सकता है जिनके पास डिफ़ॉल्ट निर्माता नहीं है, इसलिए सभी समान नियम लागू होते हैं।

1) शब्दार्थ, संदर्भों का डिफ़ॉल्ट मान नहीं होता है। संदर्भ केवल कुछ का संदर्भ लेकर बनाया जा सकता है। संदर्भ की अनुपस्थिति का प्रतिनिधित्व करने के लिए संदर्भ का कोई मूल्य नहीं है।

2) एक्स के एक सरणी को आवंटित करते समय, प्रोग्राम डिफ़ॉल्ट-प्रारंभिक ऑब्जेक्ट्स का एक संग्रह बनाता है। चूँकि संदर्भ में डिफ़ॉल्ट मान नहीं होता है, ऐसे सरणी बनाना शब्दार्थ रूप से अवैध है।

यह नियम उन ढांचों / वर्गों पर भी लागू होता है जिनमें डिफ़ॉल्ट निर्माता नहीं है। निम्नलिखित कोड नमूना संकलित नहीं करता है:

struct Object
{
    Object(int value) { }
};

Object objects[1]; // Error: no appropriate default constructor available

1
आप एक सरणी बना सकते हैं Object, आपको बस उन सभी को शुरू करना सुनिश्चित करना होगा Object objects[1] = {Object(42)};:। इस बीच, आप संदर्भों की एक सरणी नहीं बना सकते, भले ही आप उन सभी को इनिशियलाइज़ करें।
एंटोन 3

4

आप इस टेम्पलेट संरचना के साथ काफी करीब हो सकते हैं। हालांकि, आपको उन अभिव्यक्तियों के साथ आरंभ करने की आवश्यकता है जो टी के बजाय टी के संकेत हैं; और इसलिए, हालांकि आप आसानी से 'नकली_कॉन्स्ट्रेफ_र्रे' बना सकते हैं, वैसे ही आप ओपी के उदाहरण ('8') में किए गए बदलावों को बांध नहीं पाएंगे;

#include <stdio.h>

template<class T, int N> 
struct fake_ref_array {
   T * ptrs[N];
  T & operator [] ( int i ){ return *ptrs[i]; }
};

int A,B,X[3];

void func( int j, int k)
{
  fake_ref_array<int,3> refarr = { &A, &B, &X[1] };
  refarr[j] = k;  // :-) 
   // You could probably make the following work using an overload of + that returns
   // a proxy that overloads *. Still not a real array though, so it would just be
   // stunt programming at that point.
   // *(refarr + j) = k  
}

int
main()
{
    func(1,7);  //B = 7
    func(2,8);     // X[1] = 8
    printf("A=%d B=%d X = {%d,%d,%d}\n", A,B,X[0],X[1],X[2]);
        return 0;
}

-> ए = 0 बी = 7 एक्स = {0,8,0}


2

एक संदर्भ ऑब्जेक्ट का कोई आकार नहीं है। यदि आप लिखते हैं sizeof(referenceVariable), तो यह आपके द्वारा संदर्भित वस्तु का आकार देगा referenceVariable, न कि केवल संदर्भ का। इसका अपना कोई आकार नहीं है, यही वजह है कि कंपाइलर गणना नहीं कर सकता है कि सरणी को कितने आकार की आवश्यकता होगी।


3
यदि ऐसा है तो फिर कंपाइलर केवल रेफरी वाली संरचना के आकार की गणना कैसे कर सकता है?
जस्ट

कंपाइलर एक संदर्भ के भौतिक आकार को जानता है - यह एक पॉइंटर के समान है। संदर्भ, वास्तव में, शब्दार्थ रूप से महिमामंडित संकेत हैं। बिंदुओं और संदर्भों के बीच का अंतर यह है कि संदर्भ में उन बिंदुओं की संख्या को कम करने के लिए उन पर कुछ शब्दार्थ नियम हैं जिन्हें आप बिंदुओं की तुलना में बना सकते हैं।
कृत्तुस ए।

2

जब आप किसी सरणी में कुछ स्टोर करते हैं, तो उसके आकार को ज्ञात करने की आवश्यकता होती है (क्योंकि सरणी अनुक्रमण आकार पर निर्भर करता है)। C ++ मानक के अनुसार यह अनिर्दिष्ट है कि संदर्भ के लिए भंडारण की आवश्यकता है या नहीं, परिणामस्वरूप संदर्भों की एक सरणी अनुक्रमण संभव नहीं होगा।


1
लेकिन कहा संदर्भ में struct, जादुई रूप से सब कुछ निर्दिष्ट, अच्छी तरह से परिभाषित, गारंटीकृत, और नियतात्मक आकार का हो जाता है। इसलिए, क्या यह पूरी तरह से कृत्रिम अंतर मौजूद है?
अंडरस्कोर_ड

... बेशक, अगर कोई वास्तव में सोचना शुरू कर देता है कि रैपिंग में क्या structगड़बड़ है, तो कुछ अच्छे संभावित उत्तर खुद ही सुझाए जाने लगते हैं - लेकिन मेरे लिए, किसी ने भी अभी तक ऐसा नहीं किया है, इसके बावजूद सभी आम लोगों के लिए तात्कालिक चुनौती है। क्यों आप उपयोग नहीं कर सकते हैं के लिए परिमेय refs।
अंडरस्कोर_ड

2

बस सभी बातचीत में जोड़ने के लिए। चूंकि सरणियों में आइटम को संग्रहीत करने के लिए लगातार मेमोरी स्थानों की आवश्यकता होती है, इसलिए यदि हम संदर्भों की एक सरणी बनाते हैं, तो यह गारंटी नहीं है कि वे लगातार मेमोरी स्थान पर होंगे इसलिए एक्सेस करना एक समस्या होगी और इसलिए हम सभी गणितीय कार्यों को भी लागू नहीं कर सकते हैं सरणी।


मूल प्रश्न से नीचे दिए गए कोड पर विचार करें: int a = 1, b = 2, c = 3; int & arrest [] = {a, b, c, 8}; बहुत कम संभावना है कि ए, बी, सी लगातार मेमोरी स्थान पर निवास करेंगे।
अमित कुमार

यह एक कंटेनर में संदर्भ रखने की अवधारणा के साथ मुख्य समस्या से दूर है।
अंडरस्कोर_ड

0

बिंदुओं की एक सरणी पर विचार करें। एक सूचक वास्तव में एक पता है; इसलिए जब आप ऐरे को इनिशियलाइज़ करते हैं, तो आप कंप्यूटर को एनालॉग रूप से कह रहे होते हैं, "इन X नंबरों (जो अन्य आइटम्स के पते हैं) को होल्ड करने के लिए मेमोरी के इस ब्लॉक को आवंटित करें।" फिर अगर आप किसी एक पॉइंटर्स को बदलते हैं, तो आप बस वही बदल रहे हैं जो इसे इंगित करता है; यह अभी भी एक संख्यात्मक पता है जो स्वयं उसी स्थान पर बैठा है।

एक संदर्भ एक उपनाम के अनुरूप है। यदि आप संदर्भों की एक सरणी की घोषणा करते हैं, तो आप मूल रूप से कंप्यूटर को बताएंगे, "स्मृति के इस अनाकार बूँद को आवंटित करें जिसमें इन सभी अलग-अलग वस्तुओं को बिखरा हुआ है।"


1
तब, structजिसका एकमात्र सदस्य किसी चीज को पूरी तरह से कानूनी, अनुमानित, और गैर-अनाकार में संदर्भ परिणाम देता है? उपयोगकर्ता को इसके लिए संदर्भ-सक्षम शक्तियों को जादुई रूप से प्राप्त करने के लिए एक संदर्भ क्यों लपेटना चाहिए, या क्या यह सिर्फ एक कृत्रिम प्रतिबंध है? IMO ने कोई जवाब नहीं दिया है। मुझे लगता है कि खंडन है 'रैपिंग ऑब्जेक्ट यह सुनिश्चित करता है कि आप रैपिंग ऑब्जेक्ट के रूप में मूल्य शब्दार्थ का उपयोग कर सकते हैं, इसलिए यह सुनिश्चित करता है कि आपके पास मूल्यों की गारंटी हो सकती है, जिनकी आवश्यकता है क्योंकि जैसे कि तत्व और रेफरी पते के बीच कोई अंतर कैसे होगा' ... क्या आपका आशय यही था?
अंडरस्कोर_ड

-2

दरअसल, यह C और C ++ सिंटैक्स का मिश्रण है।

आपको या तो शुद्ध C सरणियों का उपयोग करना चाहिए , जो संदर्भों का नहीं हो सकता है, क्योंकि संदर्भ केवल C ++ का हिस्सा हैं। या आप C ++ तरीका जाना और अपने उद्देश्य के लिए std::vectorया std::arrayवर्ग का उपयोग करें ।

जैसा कि संपादित भाग के लिए: भले ही structसी से एक तत्व है, आप एक निर्माता और ऑपरेटर कार्यों को परिभाषित करते हैं, जो इसे सी ++ बनाते हैं class। नतीजतन, आपका structशुद्ध सी में संकलन नहीं होगा!


अापका नजरिया क्या है? std::vectorया std::arrayसंदर्भ शामिल नहीं कर सकते हैं। सी ++ मानक काफी स्पष्ट है कि कोई भी कंटेनर नहीं कर सकता है।
अंडरस्कोर_ड
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.