To search the first occurence of a element in a C-Array with POD elements, one ease can do this with std::find_if(begin, end, findit)
. But I needed the last occurence. This answer gave me the idea that this can be done with std::reverse_iterator
. Thus I tried:
std::find_if(std::reverse_iterator<podtype*>(end),
std::reverse_iterator<podtype*>(begin),
findit);
This gave me the error:
cannot convert 'std::reverse_iterator< xyz* > ' to 'xyz*' in assignment
Do you have an idea how to do it this way or do you know a better solution?
This is the code:
#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;
}
And the compiler error on codepad.org
The std::find_if
function has a return type equal to the type of iterator passed in as a parameter. In your case, since you're passing in std::reverse_iterator<xyz*>
s as parameters, the return type will be std::reverse_iterator<xyz*>
. This means that
found = std::find_if(std::reverse_iterator<xyz*>(end),
std::reverse_iterator<xyz*>(begin),
findit);
won't compile, because found
is an xyz*
.
To fix this, you can try this:
std::reverse_iterator<xyz*>
rfound = std::find_if(std::reverse_iterator<xyz*>(end),
std::reverse_iterator<xyz*>(begin),
findit);
This will fix the compiler error. However, I think that you two secondary errors in this line:
if (found != std::reverse_iterator<xyz*>(end));
First, note that you have a semicolon after the if
statement, so the body of the if
statement will be evaluated regardless of whether the condition is true.
Second, note that std::find_if
returns the second iterator as a sentinel if the nothing matches the predicate. Consequently, this test should be
if (rfound != std::reverse_iterator<xyz*>(begin))
because find_if
will return std::reverse_iterator<xyz*>(begin)
if the element is not found.
Hope this helps!