I want to have a function with interface like this:
template<typename T, typename R> int find_index (const T& list, const R& value);
As I know, there is find() in STL that returns iterator. I need to return index of iterator (even for non-indexed containers such as std::list). I tried this code:
template<typename T, typename R>
int find_index (const T& list, const R& value)
{
int index = 0;
for (T::const_iterator it = list.begin(); it != list.end(); it++, index++)
if ((*it) == value)
return index;
return -1;
}
But compiler shows error on it – seems like it is not allowed to get const_iterator from templated typename. Can I go around it?
At the worst case I can pass begin and end iterators to find_index arguments, but it looks not so fine. Would be thankful for elegant solution.
should solve your problem.
When using dependent types (types depending on template parameters), the compiler does not know that
const_iteratoris a type until it instantiates the template with a concrete type, it could also just be a static variable or whatever. Using thetypenamekeyword, you tell him thatconst_iteratoris really a type.In C++11 you can also circumvent the whole
typenameissue using theautokeyword:If you already have the iterator (maybe from some other operation), you can also just compute the distance from the list’s begin to this iterator:
But since this has linear complexity for a
std::list, using your self-madefind_indexfunction is a better idea thanstd::findfollowed bystd::distance, at least performance-wise.