STL Algorithms and Constants

Today I wrote a small predicate to search for matching characters in a container.

But I ran into a problem: I want to use this predicate in a call to std::find_if inside the class's const method, looking in the container that is a member of this class.

But I just noticed that neither std::find nor std::find_if can work on const_iterators !

I checked some C ++ links and it seems that there is no version of std::find or std::find_if that accept / return const_iterators . I just can't understand why, because from what I saw, there is no way that these algorithms can modify the object referenced by the iterator.

This is how std::find documented in the SGI implementation:

Returns the first iterator I to the range [first, last], such that * i == value. Returns the last if no iterator exists.

+4
source share
5 answers

std::find and std::find_if can definitely work on *::const_iterator for a given container. Do you happen to look at the signatures of these functions and don’t understand them?

 template <class InputIterator, class Type> InputIterator find(InputIterator first, InputIterator last, const Type& val); 

Please note that InputIterator here is just the name of the template type parameter, and any const_iterator will satisfy the requirements for it.

Or maybe you are confusing const_iterator (i.e. an iterator referring to the value of const) with a const iterator (i.e. an iterator that is itself const )?

+13
source

std::find and std::find_if both take an iterator type as a template parameter, so they can certainly work 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 working C ++ compiler and produce results such as:

3 found in position: 20

+5
source

I had the same problem. I had a member function that called find_if on a member vector, and the compiler gave me an error when I tried to create a const member function. It turned out that this was because I was assigning the return value of find_if iterator instead of const_iterator . Called by the compiler to assume that the find_if parameters find_if also be an iterator instead of a const_iterator that it could not get from the const member vector.

+1
source

If you happen to be 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)' 

This has nothing to do with const_iterator s. You probably just forgot #include <algorithm>

0
source

I had a problem 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 "does not match the overload for std :: find".

The fix I needed was to use cend (). This is confusing that cbegin () is not required, I'm not sure why this conversion is in order (implicitly) and not for end () as a function parameter.

0
source

All Articles