Iterators - Overload Functions for Vector :: Iterator and Array :: Iterator

I am trying to overload a specific function, so that iterators of adjacent containers (which are std :: vector :: iterator, std :: array :: iterator and inline arrays iterators == raw pointers) can be a valid argument.

for some reason my functions will not compile for vector and std :: array:

features:

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 } 

usage example:

 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 am using VC ++ with RTM for Visual Studio 2015.

The errors are pretty clear, but I wonder if the compiler really couldn’t deduce T and N from it and it0, after all, this is part of its / it 0 type ..

how to do it?

Edit:
I will go with the @ForEveR clause and pass the + iterator / index container as arguments. thanks!

+5
source share
1 answer

Your functions cannot work, since the compiler cannot output T and N from the iterator that you send to the 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 a problem if vector::iterator and array::iterator are of the same type (for example, on gcc) - the code will not compile, because the compiler will not know which function it should use.

The best way is to simply pass the container as the first argument and the iterator as the 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 } 
+4
source

Source: https://habr.com/ru/post/1240701/


All Articles