STL algorithms and const_iterators
Today I wrote a small predicate to find matching symbols in a container.
But I'm faced to a problem: I want to use this predicate in a std::find_if
call inside a const-method of a class, searching in a container that is a member of this class.
But I just noticed that neither std::find
nor std::find_if
are able to operate on const_iterators
!
I checked on some C++ references and it seems there is no version of std::find
or std::find_if
that accept/return const_iterators
. I just can't understand why, since from what I've seen, there is no way that these algorithms could modify the object referenced by the iterator.
Here is how is documented std::find
in the SGI implementation:
Returns the first iterator i in the range [first, last) such that *i == value. Retur开发者_StackOverflow中文版ns last if no such iterator exists.
std::find
and std::find_if
can definitely operate on *::const_iterator
for a given container. Are you by chance looking at the signatures of those functions, and misunderstanding them?
template <class InputIterator, class Type>
InputIterator find(InputIterator first, InputIterator last, const Type& val);
Note that InputIterator
here is just a name of a template type parameter, and any const_iterator
will satisfy the requirements for it.
Or, perhaps, you're confusing const_iterator
(i.e. an iterator referencing a const value) with a const
iterator (i.e. an iterator which is itself const
)?
std::find
and std::find_if
both take the iterator type as a template parameter, so they most certainly can operate on const_iterators
. Just for a quick example:
#include <vector>
#include <algorithm>
#include <iostream>
int main() {
std::vector<int> x;
std::fill_n(std::back_inserter(x), 20, 2);
x.push_back(3);
std::vector<int>::const_iterator b = x.begin();
std::vector<int>::const_iterator e = x.end();
std::vector<int>::const_iterator p = std::find(b, e, 3);
std::cout << *p << " found at position: " << std::distance(b, p) << "\n";
return 0;
}
This should be accepted by any properly functioning C++ compiler, and produce results like:
3 found at position: 20
I have just had the same problem. I had a member function that was calling find_if
on a member vector, and the compiler gave me an error when I tried making the member function const
. It turned out that this was because I was assigning the return value of find_if
to an iterator
instead of const_iterator
. The caused the compiler to assume that the parameters of find_if
must also be iterator
instead of const_iterator
, which it could not get from the const
member vector.
If by any chance you are here for the same reason as me:
error: no matching function for call to ‘find(std::vector<int>::const_iterator, std::vector<int>::const_iterator, int)’
It doesn't have anything to do with const_iterator
s. You probably just forgot to #include <algorithm>
:-)
I just had an issue with this code:
std::string str;
std::string::const_iterator start = str.begin();
std::string::const_iterator match = std::find(start, str.end(), 'x');
The error was "no matching overload for std::find".
The fix I needed was to use cend(). It's confusing that cbegin() isn't required, I'm not sure why that conversion is okay (implicitly) and not for the end() as a function parameter.
精彩评论