2012-05-14 14 views
10

व्यावहारिक उपयोग के संदर्भ में क्या मतभेदcopy_backward या reverse_iterators के साथ प्रतिलिपि बनाएँ?

के बीच देखते हैं क) copy_backward

ख) स्रोत और गंतव्य के लिए reverse_iterators साथ कॉपी

विशेष रूप से एक और अन्य की तुलना में लागू होता है? क्या कोई और अंतर है?

अद्यतन: यदि वास्तव में कोई अंतर नहीं है, तो इस समकक्षता के लिए सी ++ साहित्य में कोई संदर्भ सराहना की जाती है। इस सवाल के पीछे प्रेरणा यह समझना है कि क्या यह डिज़ाइन या उन पर्ची अपों में से एक है (जैसे अनुपलब्ध copy_if)

+0

मुझे आश्चर्य नहीं होगा अगर, 'रिवर्स_इटरेटर' का उपयोग करते हुए, इटरेटर प्रकार को सही ढंग से टैग करने की आवश्यकता होती है जबकि 'copy_backward' को सरल लूप के रूप में कार्यान्वित किया जाता है। जाहिर है कि इसकी गारंटी नहीं है, यद्यपि। जहां तक ​​मानक का संबंध है, सभी इटरेटर को टैग किया जाना चाहिए। –

+0

हम्म ... एक ही पंक्तियों के साथ मूल पुनरावर्तक एक टी * के मामले में शायद धीमा हो सकता है? – hawk

+0

'टी *' को एक यादृच्छिक-एक्सेस इटरेटर के रूप में टैग किया गया है, क्योंकि एक गारंटीकृत आंशिक विशेषज्ञता 'टेम्पलेट संरचना iterator_traits ; '। –

उत्तर

-1

व्यावहारिक रूप से कोई अंतर नहीं है। उसी तरह आप आगे की प्रतिलिपि की तुलना कर सकते हैं।

क) रिवर्स iterators साथ कॉपी

ख) copy_backward।

+1

यह तकनीकी रूप से सत्य नहीं है क्योंकि प्रतिलिपि अधिक सामान्य है जिसमें इसका उपयोग इनपुट/आउटपुट इटरेटर के साथ किया जा सकता है। इसे बिडरेक्शनल इटरेटर्स की आवश्यकता नहीं है। – hawk

+1

तो आपने अपने प्रश्न का उत्तर दिया =) एक तकनीकी अंतर है। – inkooboo

+2

@inkooboo: यह आपके (ए) और (बी) के बीच एक अंतर है: किसी को कम से कम एक द्विपक्षीय इटरेटर की आवश्यकता होती है, और दूसरा नहीं। वही अंतर हैक (ए) और (बी) पर लागू नहीं होता है, क्योंकि दोनों को कम से कम एक द्विपक्षीय इटरेटर की आवश्यकता होती है। –

-1

कोई अंतर नहीं होना चाहिए, हालांकि: प्रतिलिपिकर्ता कुछ फ़ंक्शन कॉल का परिणाम होता है और रिवर्स इटरेटर्स के साथ प्रतिलिपि बनाने से भी अधिक क्लीनर होता है।

5

सबसे पहले, copy_backward() का उपयोग स्पष्ट रूप से रिवर्स ऑर्डर में अंतराल की प्रतिलिपि बनाने के लिए डेवलपर के इरादे को दिखाता है।

copy_backward() मूल बिडरेक्शनल इटरेटर्स के साथ काम करता है, जबकि रिवर्स_इटरेटर बिडरेक्शनल इटरेटर का एडाप्टर है और मूल इटरेटर के रूप में प्रभावी नहीं हो सकता है।

रिवर्स_इटरेटर का उपयोग करना समझ में आता है जब आपको प्रतिलिपि अनुक्रमित करने के लिए प्रतिलिपि() जैसे इनपुट इटरेटर के लिए एल्गोरिदम लागू करने की आवश्यकता होती है, लेकिन प्रतिलिपि बनाने वाले ऑपरेटरों जैसे copy_backward() के समकक्ष नहीं है।

इसलिए, अवधारणा और व्यावहारिक मतभेद हैं।

1

http://www.cplusplus.com/reference/algorithm/copy/std::copy

http://www.cplusplus.com/reference/algorithm/copy_backward/ के एक कार्यान्वयन है std::copy_backward

के कार्यान्वयन आप खुद अंतर देख सकते है।

नोट: अगर मैं तुम्हें थे मैं std::copy_backward का प्रयोग करेंगे, क्योंकि std::reverse_iterator<T> वर्ग के साथ std::copy बुला थोड़ी धीमी हो सकती है

0

अंतर यह है कि copy एक रिटर्न है (यह एक द्विदिश इटरेटर से अधिक स्मृति की आवश्यकता) पास-द-एंड तत्व के लिए इटरेटर जबकि copy_backward पहले तत्व में इटरेटर लौटाता है।

वे उस अर्थ के बराबर नहीं हैं।

  • पाठ्यक्रम के हस्ताक्षर अलग-अलग हैं। copyInputIterator एस और OutputIterator के साथ ठीक है। जबकि copy_backwardBidirectionalIterator एस की अपेक्षा करता है।
  • कंटेनर पर प्रभाव (जब सही ढंग से उपयोग किया जाता है) वही है, लेकिन लौटाए गए इटरेटर विभिन्न प्रकार के होते हैं और विभिन्न तत्वों को इंगित करते हैं।

उदाहरण:

यह काम करता है क्योंकि vector गुण InputIterator, OutputIterator और BidirectionalIterator से उम्मीद का समर्थन करता है जो RandomAccessIterator उपयोग कर सकते हैं।

#include <iostream> 
#include <algorithm> 
#include <vector> 
using namespace std; 

void printer(int i) { 
    cout << i << ", "; 
} 

int main() { 

    int mynumbers[] = {3, 9, 0, 2, 1, 4, 5}; 
    vector<int> v1(mynumbers, mynumbers + 7); 

    vector<int>::iterator it = copy_backward(mynumbers, mynumbers + 7, v1.end()); 
    for_each(v1.begin(), v1.end(), printer); 
    cout << endl << "Returned element: " << *it; 
    cout << endl; 

    vector<int>::reverse_iterator rit = copy(mynumbers, mynumbers + 7, v1.rbegin()); 
    for_each(v1.begin(), v1.end(), printer); 
    cout << endl << "Before the first element (reverse end)? " << (rit == v1.rend()); 
    rit--; // go to first element, because it is a reverse iterator 
    cout << endl << "Returned element: " << *rit; 

    return 0; 
} 

परिणाम:

3, 9, 0, 2, 1, 4, 5, 
Returned element: 3 
5, 4, 1, 2, 0, 9, 3, 
Before the first element (reverse end)? 1 
Returned element: 5 

आप एक कंटेनर का समर्थन नहीं करता BidirectionalIterator तो आप मुसीबत जोखिम का उपयोग करेंगे, तो (उदाहरण के लिए आप पीछे की ओर एक forward_list कॉपी करने के लिए, क्योंकि यह एक ForwardIterator का उपयोग करता है की कोशिश चाहते हैं, जो BidirectionalIterator द्वारा प्रदान किए गए संचालन का समर्थन नहीं करता है)।
इस मामले में forward_list पर रिवर्स इटरेटर के साथ प्रतिलिपि भी संभव नहीं है, क्योंकि यह रिवर्स इटरेटर्स का समर्थन नहीं करता है।

असल में, आपको यह सुनिश्चित करना होगा कि कंटेनर के इटरेटर समर्थित हैं और उस कंटेनर के अंत के अनुसार चुनें जिसे आप वापस करना चाहते हैं। अन्यथा प्रभाव वही है।

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