Reputation: 81
I'm experimenting with the "find" function. I can't seem to be able to return the iterator.
template<typename T>
typename T::iterator do_find(const T &v, int f)
{
return find(v.begin(), v.end(), f);
}
And here is my main :
int main()
{
std::vector<int> v = {1, 2, 3, 3, 4, 6};
std::vector<int>::iterator it;
it = do_find(v, 3);
return 0;
}
When I compile I get the following error :
error: impossible de convertir
« std::find<__gnu_cxx::__normal_iterator<const int*, std::vector<int> >, int>((& v)->std::vector<int>::begin(), (& v)->std::vector<int>::end(), f) » de « __gnu_cxx::__normal_iterator<const int*, std::vector<int> > » vers « std::vector<int>::iterator {aka __gnu_cxx::__normal_iterator<int*, std::vector<int> >} »
Upvotes: 2
Views: 577
Reputation: 172924
v
is declared as const
, then for std::vector
, both v.begin()
and v.end()
return std::vector::const_iterator
, then the return type of find
will be std::vector::const_iterator
too; it can't be converted to std::vector::iterator
implicitly.
You can change the return type, e.g.
template<typename T>
typename T::const_iterator do_find(const T &v, int f)
{
return find(v.begin(), v.end(), f);
}
or just
template<typename T>
auto do_find(const T &v, int f)
{
return find(v.begin(), v.end(), f);
}
then
auto it = do_find(v, 3);
If you want to modify the element through the returned iterator, then you should declare the parameter v
to be non-const.
template<typename T>
auto do_find(T &v, int f)
{
return find(v.begin(), v.end(), f);
}
Note that with auto
, the above do_find
will return iterator
if you pass a non-const vector
, and return const_iterator
if you pass a const vector
.
Upvotes: 3
Reputation: 310980
Within the function the container is declared as a constant container
template <typename T>
typename T::iterator do_find(const T &v, int f);
^^^^^^^^^^
So the member functions begin
and end
of this container return objects of the type typename T::const_iterator
that can not be implicitly converted to the type.typename T::iterator
.
Also it is not clear why the second parameter has the type int
instead of the type typename T::value_type
.
There is a magic word auto
in C++ that can simplify the function declaration and using its return value.
The function can be defined the following way
template <typename T>
auto do_find( const T &v, typename T::value_type value ){
return std::find( v.begin(), v.end(), value );
}
Here is a demonstrative program
#include <iostream>
#include <vector>
#include <algorithm>
#include <iterator>
template <typename T>
auto do_find( const T &v, typename T::value_type value ){
return std::find( v.begin(), v.end(), value );
}
int main()
{
std::vector<int> v = { 1, 2, 3, 3, 4, 6 };
auto it = do_find(v, 3);
if ( it != v.end() )
{
std::cout << *it << " is found at position "
<< std::distance( v.cbegin(), it ) << std::endl;
}
return 0;
}
Its output is
3 is found at position 2
Upvotes: 0
Reputation: 6983
v
is const
; meaning that std::find
will return a T::const_iterator
. You're attempting to return a T::iterator
; and the compiler can't convert from const
to non-const.
The fix is to either return the const_iterator
or to make v
non-const. Depending on exactly what you want to do with the iterator.
Upvotes: 1