2011-01-21 18 views
13

मैं एक सरणी के अंतिम तत्व के बाद एक सूचक की ओर इशारा करते प्राप्त करने के लिए निम्नलिखित टेम्पलेट का उपयोग के अंत तक एक सूचक प्राप्त करना:एक सरणी

template <typename T, size_t n> 
T* end_of(T (&array)[n]) 
{ 
    return array + n; 
} 

अब मैं याद करने के लिए इस दृष्टिकोण के साथ कुछ समस्या रही हो लग रहे हैं , लेकिन मुझे याद नहीं है कि यह क्या था। मेरा मानना ​​है कि इसमें टाइप पैरामीटर या फ़ंक्शन पैरामीटर की पसंद के साथ कुछ था, लेकिन मुझे यकीन नहीं है। तो बस एक सैनिटी चेक के रूप में, क्या आप उपरोक्त कोड के साथ कोई समस्या देखते हैं? छोटे उपयोग परीक्षण:

int test[] = {11, 19, 5, 17, 7, 3, 13, 2}; 
std::sort(test, end_of(test)); 
+0

चूंकि आपको फ़ंक्शन में सरणी के आकार में गुजरना है, इसलिए आप वास्तव में क्या प्राप्त कर रहे हैं कि आप 'सरणी' टेम्पलेट का उपयोग करके प्राप्त नहीं कर पाएंगे? –

+0

@Zac: मुझे नहीं, फ़ंक्शन में केवल एक पैरामीटर है। टेम्पलेट पैरामीटर 'n' स्वचालित रूप से कम हो जाता है, उदाहरण के कोड में देखा गया है कि आप केवल 'end_of (array)' कहते हैं। – fredoverflow

+0

उस स्थिति में, जिस समस्या में आप भागेंगे, वह गतिशील सरणी से निपट रहा है क्योंकि 'n' केवल एक ही 'टी' का आकार होगा। –

उत्तर

8

आपके प्रस्ताव का संकलन समय पर मूल्यांकन नहीं किया जाता है, यह अनुकूलन पर निर्भर करता है। निम्नलिखित संकलन समय पर की जाती है:

template <typename T, size_t N> char (&array(T(&)[N]))[N]; 

int main() 
{ 
    int myArray[10]; 

    std::cout << sizeof array(myArray) << std::endl; 

    return 0; 
} 

यह चार की एक सरणी प्रकार है जो दिए गए सरणी के रूप में तत्वों की एक ही नंबर है बनाकर काम करता है। आकार हमेशा वर्णों की संख्या में आकार देता है।

+0

आह, मुझे पूरा यकीन है कि यह समस्या मेरे मन में थी। धन्यवाद! समस्या लाने के लिए – fredoverflow

+0

+1। तकनीकी रूप से यह नहीं है कि संकलन समय पर इसका मूल्यांकन नहीं किया जाता है, बल्कि यह भी कि संकलन समय पर मूल्यांकन किए जाने पर भी, मान संकलन समय स्थिर नहीं है। –

1

आपको एक कॉन्स संस्करण भी चाहिए। हालांकि, जहां तक ​​मुझे पता है, उस दृष्टिकोण के साथ कोई वास्तविक समस्या नहीं है- मुझे लगता है कि यह आमतौर पर उपयोग किया जाता है।

+1

नहीं, उपरोक्त कोड 'const' arrays के साथ भी काम करता है। यदि आप 'कॉन्स फू [एन]' सरणी पास करते हैं, तो 'टी'' को 'फू' के बजाय 'कॉन्स्ट फू' ​​के रूप में घटाया जाता है। – fredoverflow

+1

@Fred सही है। यह केवल 'end_of (ए() ए) के लिए विफल रहता है;' जहां 'ए' को 'ए' ए 'int [1] द्वारा परिभाषित किया गया है; }; '(rvalueness और गैर-कॉन्स्ट संदर्भ के कारण), लेकिन मुझे लगता है कि यह बुरा नहीं है बल्कि इस मामले में एक अच्छी बात है। –

2

एकमात्र समस्या जो मैं देखता हूं वह यह है कि यदि आप कभी संकलन समय पर लंबाई नहीं जानते हैं, तो आपका टेम्पलेट नहीं जानता कि वहां क्या रखा जाए। तो आपको test+x या कुछ भी कहना होगा, और अब आपके पास एक ही काम करने के दो अलग-अलग तरीके हैं।

व्यक्तिगत रूप से मैं सिर्फ vector<int> का उपयोग करता हूं और इस प्रकार end() पहले से ही मेरे लिए परिभाषित किया गया है। यदि आपको कभी भी सरणी की आवश्यकता है, तो यह &v[0] के रूप में उपलब्ध है।

+1

आमतौर पर, कंपाइलर एक सरणी के आकार को जानता है (केवल अपवाद तब होता है जब आप इसे आकार प्रदान किए बिना बाहरी घोषित करते हैं, और उसके बाद सरणी को एक अलग अनुवाद इकाई में परिभाषित करते हैं)। यह टेम्पलेट का पूरा बिंदु है। आप टेम्पलेट में किसी सरणी के पहले तत्व में पॉइंटर पास नहीं कर सकते हैं, क्योंकि एक सूचक एक सरणी नहीं है। – fredoverflow

+1

@ चाओ: आप 'std :: array' का भी उपयोग कर सकते हैं और 'end()' फ़ंक्शन पहले ही परिभाषित किया गया है (स्थिर आकार के सरणी के लिए)। –

+0

तो, सरणी के लिए आप 'end_of (ए)' का उपयोग करते हैं, और पॉइंटर्स के लिए आप 'ए + 8' का उपयोग करते हैं? और निश्चित रूप से, एसटीएल कंटेनर के लिए आप 'a.end() 'का उपयोग करते हैं ... – cHao