2012-09-30 22 views
5

मैं वर्तमान में निम्नलिखित समारोह किसी सरणी या कच्चे डेटा का एक वेक्टर (_readStream एक std::ifstream है) को पढ़ने के लिए:यह जांचने के लिए कि क्या Iterators एक संगत स्मृति क्षेत्र बनाते हैं?

template<typename IteratorType> 
inline bool MyClass::readRawData(
    const IteratorType& first, 
    const IteratorType& last, 
    typename std::iterator_traits<IteratorType>::iterator_category* = nullptr 
    ) 
{ 
    _readStream.read(reinterpret_cast<char*>(&*first), (last-first)*sizeof(*first)); 
    return _readStream.good(); 
} 

पहला सवाल: इस समारोह आप के लिए ठीक प्रतीत होता है?

जैसा कि हम सीधे स्मृति के एक ब्लॉक को पढ़ते हैं, यह केवल तभी काम करेगा जब मेमोरी ब्लॉक first से last स्मृति में संगत है। इसे कैसे जांचें? क्योंकि std::iterator_traits एक unconditonally परिभाषित सदस्य प्रकार iterator_category के साथ एक प्राथमिक टेम्पलेट है

+0

आपका फ़ंक्शन इस बारे में बहुत सारी धारणा करता है कि इसका उपयोग कैसे किया जाएगा। यह बेहतर होगा अगर वे स्पष्ट थे, या कम से कम दस्तावेज थे। इन धारणाओं में से: 1) उन तत्वों को स्मृति में उनके द्विआधारी प्रतिनिधित्व द्वारा क्रमबद्ध किया जा सकता है। 2) कि रनटाइम का अंतहीनता डेटा लिखने वाले जैसा ही है। – Cameron

+3

दरअसल, फ़ंक्शन पूरी तरह से गैर-जेनेरिक होने पर इटरेटर का उपयोग क्यों करते हैं? इसका एकमात्र उद्देश्य स्मृति की प्रतिलिपि तत्वों को प्रतिलिपि बनाना है। इसे प्रतिबिंबित करने के लिए फ़ंक्शन का नाम बदलें, और इसे इटरेटर्स की बजाय पॉइंटर और गिनती लें ... आपके शीर्षक में प्रश्न अभी भी दिलचस्प है हालांकि :-) – Cameron

+0

यदि अंतहीनता अलग थी तो डेटा को स्वैप करने के लिए मेरे पास एक और फ़ंक्शन है ताकि आपका दूसरा बिंदु एक समस्या नहीं है। – Vincent

उत्तर

4

अपने नमूना फ़ंक्शन को छोड़कर, आप कभी भी पूरी तरह से यह सुनिश्चित नहीं कर सकते कि इटरेटर दोनों के बीच प्रत्येक तत्व के पते की जांच किए बिना एक संगत स्मृति बनाएंगे।

एक उचित विवेक परीक्षण, हालांकि, सिर्फ जांच करने के लिए हो सकता है अगर दोनों के बीच स्मृति क्षेत्र दोनों के बीच गिनती रूप में ही है:

assert(&*last - &*first == last - first && 
    "Iterators must represent a contiguous memory region"); 
+1

मुझे पूरा यकीन है कि '& * अंतिम - और * पहला 'अनिश्चित व्यवहार है जब तक कि * * पहले' और' * अंतिम 'एक ही सरणी का हिस्सा हैं, और यही वह चीज है जिसे हम निर्धारित करने की कोशिश कर रहे हैं। –

+0

@ बेंजामिन लिंडली मुझे नहीं लगता कि यह अपरिभाषित होगा - यह केवल सूचक सूचक है। यदि कंटेनर संगत नहीं है, तो हमें नकारात्मक मूल्यों जैसे कुछ अजीब परिणाम मिल सकते हैं, लेकिन यह दो पुनरावृत्तियों के बीच की दूरी के विरुद्ध जांच की जाएगी। मुझे लगता है कि यह मानना ​​काफी सुरक्षित है कि पोस्टर को कम से कम अपने एल्गोरिदम की आवश्यकता होगी ताकि एक ही कंटेनर से यादृच्छिक-एक्सेस इटरेटर्स की आवश्यकता हो या नहीं कि कंटेनर संगत है या नहीं। फिर भी, यह एक अजीब बात है कि पोस्टर करने की कोशिश कर रहा है। – stinky472

+7

@ stinky472: हाँ, मैं समझता हूं कि यह पॉइंटर घटाव है। मैं जो कह रहा हूं वह यह है कि जब तक पॉइंटर्स एक ही सरणी में ऑब्जेक्ट्स को इंगित नहीं करते हैं, तो मानक के अनुसार, 5.7.6 –

2
typename std::iterator_traits<IteratorType>::iterator_category* = nullptr 

यह बेकार है। यह स्पष्ट रूप से माना जाता है कि टेम्पलेट पैरामीटर एक पुनरावर्तक है और यह एक पूर्व शर्त उल्लंघन है यदि यह नहीं है - जैसे कि आपको SFINAE नहीं मिलेगा, लेकिन उपरोक्त अमान्य अस्थायीता के साथ प्रयास किया गया है तो एक कठिन त्रुटि।

जैसा कि हम सीधे स्मृति के एक ब्लॉक को पढ़ते हैं, यह केवल तभी काम करेगा जब मेमोरी ब्लॉक पहले से आखिरी तक स्मृति में सम्मिलित है। इसे कैसे जांचें?

मुझे नहीं पता कि आप 'स्मृति में संगत' अवधारणा पर क्या सटीक आवश्यकताओं को रखेंगे। क्या आपने निम्नलिखित को माना है?

template<typename T> 
bool readRawData(T* first, T* last); 
पूर्व शर्त है कि एक सरणी में एक वैध सूचक के रूप में इटरेटर सीमा हो [ first, last) साथ

यदि आप T पर अधिक आवश्यकताएं डालना चाहते हैं (उदाहरण के लिए आप read का उपयोग करते हैं तो तुच्छ प्रतिलिपि बनाने योग्यता) आप उन्हें भी व्यक्त/दस्तावेज कर सकते हैं।

3

n4183 एक कागज है कि के विचार ऊपर से निकलता है एक संगत इटरेटर विशेषता जोड़ना। वर्तमान में यह सी ++ 1z (उम्मीद है कि सी ++ 17) के लिए विचाराधीन है।

इसके तहत, आप std::is_contiguous_iterator<It>::value कर सकते हैं और It एक संगत पुनरावर्तक है या नहीं। (इसे इटरेटर के डिजाइनर से समर्थन की आवश्यकता होगी)।

+0

क्या यह स्वीकार किया गया था? – einpoklum