Reputation: 1750
I'm stuck when doing an exercise from the book C++ Primer , which goes:
Exercise 10.24:Use bind and check_size to find the first element in a vector of ints that has a value greater than the length of a specified string value.
My code:
#include <iostream>
#include <string>
#include <vector>
#include <algorithm>
#include <functional>
bool check_size(const std::string &s, std::string::size_type sz)
{
return s.size() > sz;
}
std::vector<int>::iterator
find_first_bigger(const std::vector<int> &v, const std::string &s);
int main(){return 0;}
std::vector<int>::iterator
find_first_bigger(const std::vector<int> &v, const std::string &s)
{
auto it= std::find_if_not(v.begin(), v.end(),std::bind(check_size,s,std::placeholders::_1));
return it;
}
When trying to compile, the compiler complained that:
error: could not convert 'it' from '__gnu_cxx::__normal_iterator<const int*, std::vector<int> >' to 'std::vector<int>::iterator {aka __gnu_cxx::__normal_iterator<int*, std::vector<int> >}'
To find out what is going on,I turned to the header *stl_algo.h* in which I guess std::find_if_not is defined.The comment there said:
@return The first iterator @c i in the range @p [_first,_last)
The definition of this function:
template<typename _InputIterator, typename _Predicate>
inline _InputIterator
find_if_not(_InputIterator __first, _InputIterator __last,
_Predicate __pred)
{
// concept requirements
__glibcxx_function_requires(_InputIteratorConcept<_InputIterator>)
__glibcxx_function_requires(_UnaryPredicateConcept<_Predicate,
typename iterator_traits<_InputIterator>::value_type>)
__glibcxx_requires_valid_range(__first, __last);
return std::__find_if_not(__first, __last, __pred);
}
It seems the return type should be the same to the argument.But why complier complained so? How to fix this error?Thx.
Upvotes: 2
Views: 1393
Reputation: 229234
std::vector<int>::iterator
find_first_bigger(const std::vector<int> &v, const std::string &s);
^^
Your vector is const. So you'll get a std::vector<int>::const_iterator
.
Had it not been const, you'd get a std::vector<int>::iterator
Upvotes: 4
Reputation: 19272
Notice
//...
inline _InputIterator
find_if_not(_InputIterator __first, _InputIterator __last,
_Predicate __pred)
//...
returns the same type of iterator that it receives as a parameter.
Since you passed a const std::vector<int> &v
you must return a const_iterator
thus
std::vector<int>::const_iterator
find_first_bigger(const std::vector<int> &v, const std::string &s);
Upvotes: 3