Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Iterators - Overloading functions for vector::iterator and array::iterator

I'm trying to overload a certain function so only iterators of contiguous containers (which are std::vector::iterator ,std::array::iterator ,and built-in arrays iterators == raw pointers) can be a valid argument.

for some reason my functions fail to compile for vector and std::array :

functions:

template <class T,size_t N>
void catchIterator(typename std::array<T, N>::iterator it) {
    //do somthing
}

template <class T>
void catchIterator(typename std::vector<T>::iterator it) {
    //do somthing
}

example of use :

std::array<int, 10> arr;
auto it = arr.begin();
catchIterator(it);

std::vector<int> vec;
auto it0 = vec.begin();
catchIterator(it0);

Errors :

Error (active)      no instance of overloaded function "catchIterator" matches the argument list
Error (active)      no instance of overloaded function "catchIterator" matches the argument list    
Error   C2783   'void catchIterator(std::array<_Ty,_Size>::iterator)': could not deduce template argument for 'T'   

Error   C2783   'void catchIterator(std::array<_Ty,_Size>::iterator)': could not deduce template argument for 'N'

Error   C2672   'catchIterator': no matching overloaded function found  

I'm using VC++ with Visual studio 2015 RTM.

The errors are pretty self-explanatory, but I wonder if the compiler couldn't really deduce T and N from it and it0, after all, it is part of it/it0 type..

how can make it work?

Edit:
I'll go with @ForEveR suggestion and pass the container+iterator/index as arguments instead. thanks!

like image 742
David Haim Avatar asked Jan 15 '16 14:01

David Haim


People also ask

What is the use of iterator in vector C++?

An iterator is used to point to the memory address of the STL container classes. For better understanding, you can relate them with a pointer, to some extent. Iterators act as a bridge that connects algorithms to STL containers and allows the modifications of the data present inside the container.

What are iterators iterators are used to iterate over C like arrays?

Explanation: Iterators are STL components used to point a memory address of a container. They are used to iterate over container classes.

Can we use iterator in vector?

Use an iterator vector<int>::iterator iter; An iterator is used as a pointer to iterate through a sequence such as a string or vector . The pointer can then be incremented to access the next element in the sequence.

What is a vector iterator?

Vector's iterators are random access iterators which means they look and feel like plain pointers. You can access the nth element by adding n to the iterator returned from the container's begin() method, or you can use operator [] . std::vector<int> vec(10); std::vector<int>::iterator it = vec.


1 Answers

Your functions cannot work, since compiler cannot deduce T and N from iterator, that you send to function. You can use std::enable_if.

template <class Iterator>
typename std::enable_if<std::is_same<Iterator, typename std::array<typename std::iterator_traits<Iterator>::value_type, 1>::iterator>::value, void>::type
catchIterator(Iterator it) {
    //do somthing
}

template <class Iterator>
typename std::enable_if<std::is_same<Iterator, typename std::vector<typename std::iterator_traits<Iterator>::value_type>::iterator>::value, void>::type 
catchIterator(Iterator it) {
    //do somthing
}

But there is actually a problem if vector::iterator and array::iterator are of the same type (on gcc for example) - code will not compile, since compiler will not know which function it should use.

The best way is to just pass container as first argument and iterator as second.

template <typename T, size_t N>
void catchIterator(const std::array<T, N> &, typename std::array<T, N>::iterator it) {
    //do somthing
}

template <typename T>
void catchIterator(const std::vector<T> &, typename std::vector<T>::iterator) {
    //do somthing
}
like image 145
ForEveR Avatar answered Sep 18 '22 18:09

ForEveR