2013-06-19 4 views
9

पीओडी तत्वों के साथ सी-एरे में किसी तत्व के पहले अवसर को खोजने के लिए, एक आसानी std::find_if(begin, end, findit) के साथ ऐसा कर सकती है। लेकिन मुझे आखिरी मौके की जरूरत थी। This answer ने मुझे यह विचार दिया कि यह std::reverse_iterator के साथ किया जा सकता है। इस प्रकार मैंने कोशिश की:सी-स्टाइल सरणी पर reverse_iterator के साथ find_if का उपयोग कैसे करते हैं?

std::find_if(std::reverse_iterator<podtype*>(end), 
      std::reverse_iterator<podtype*>(begin), 
      findit); 

यह मैं त्रुटि दिया:

cannot convert 'std::reverse_iterator< xyz* > ' to 'xyz*' in assignment

क्या आप एक विचार है कि यह कैसे इस तरह से करने के लिए या आप एक बेहतर समाधान जानते हैं?

#include <iostream> 
#include <iterator> 
#include <algorithm> 

struct xyz { 
    int a; 
    int b; 
}; 

bool findit(const xyz& a) { 
    return (a.a == 2 && a.b == 3); 
} 

int main() { 
    xyz begin[] = { {1, 2}, {2, 3}, {2, 3}, {3, 5} }; 
    xyz* end = begin + 4; 

    // Forward find 
    xyz* found = std::find_if(begin, end, findit); 
    if (found != end) 
     std::cout << "Found at position " 
        << found - begin 
        << std::endl; 

    // Reverse find 
    found = std::find_if(std::reverse_iterator<xyz*>(end), 
         std::reverse_iterator<xyz*>(begin), 
         findit); 
    if (found != std::reverse_iterator<xyz*>(end)); 
     std::cout << "Found at position " 
        << found - std::reverse_iterator<xyz*>(end) 
        << std::endl; 

    return 0; 
} 

और compiler error on codepad.org

उत्तर

11

std::find_if समारोह एक वापसी प्रकार इटरेटर के प्रकार एक पैरामीटर के रूप में पारित करने के लिए बराबर है:

इस कोड है। आपके मामले में, चूंकि आप पैरामीटर के रूप में std::reverse_iterator<xyz*> एस में गुजर रहे हैं, तो वापसी का प्रकार std::reverse_iterator<xyz*> होगा। इसका मतलब है कि

found = std::find_if(std::reverse_iterator<xyz*>(end), 
        std::reverse_iterator<xyz*>(begin), 
        findit); 

संकलन नहीं होगा, क्योंकि found एक xyz* है।

इसे ठीक करने के, तो आप इस कोशिश कर सकते हैं:

std::reverse_iterator<xyz*> 
rfound = std::find_if(std::reverse_iterator<xyz*>(end), 
         std::reverse_iterator<xyz*>(begin), 
         findit); 

इस संकलक त्रुटि को ठीक होगा। हालांकि, मुझे लगता है कि आप दो इस पंक्ति में माध्यमिक त्रुटियों:

if (found != std::reverse_iterator<xyz*>(end)); 

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

दूसरा, ध्यान दें कि std::find_if दूसरे इटरेटर को सेंटीनेल के रूप में लौटाता है यदि कुछ भी भविष्य से मेल नहीं खाता है। नतीजतन, इस परीक्षण

if (rfound != std::reverse_iterator<xyz*>(begin)) 

होना चाहिए क्योंकि find_ifstd::reverse_iterator<xyz*>(begin) वापस आ जाएगी अगर तत्व नहीं मिला है।

आशा है कि इससे मदद मिलती है!

+0

हाँ यह मदद करता है, धन्यवाद। लौटा हुआ इंडेक्स अब दोनों मामलों में 1 है जो सही लगता है लेकिन रिवर्स सर्च का नतीजा 2 का सूचकांक देगा। मैं 'rfound' से 'start' घटा नहीं सकता क्योंकि इससे पहले की तरह ही त्रुटि होती है । –

+0

@ क्रिश्चियनअमेर- मुझे लगता है कि ऐसा इसलिए है क्योंकि इंडेक्स प्राप्त करने के लिए आपका तर्क गलत है। आपका घटाव रिवर्स इटरेटर से सरणी के अंतिम तत्व तक दूरी की गणना करता है, जो सरणी के पीछे * से दूरी * को देता है, सामने से नहीं। – templatetypedef

+0

मुझे लगता है कि मुझे अब मिल गया है। तर्क गलत था लेकिन '(अंत - शुरू) के साथ - (rfound - std :: reverse_iterator (अंत)) - 1' मुझे सही अनुक्रमणिका मिलती है। –

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