Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Raw int pointer vs vector::iterator<int>

I was trying to understand difference between a raw pointer and an vector iterator. However, the following program trips me out. Does template function have priority over non-template function?

Expected: hello! world!
Actual: hello! hello!

#include <bits/stdc++.h>
using namespace std;

template<typename It>
void foo(It begin, It end) {
  cout << "hello! ";
}

void foo(const int* a, const int* b, size_t n=0) {
  cout << "world! ";
}

int main() {
  vector<int> A = {5,6,7,8,9};
  int B[] = {1,2,3,4,5};
      
  foo(A.begin(), A.end());
  foo(B, B+5);

  cout << endl;
}
like image 206
Hee Hwang Avatar asked Nov 30 '25 01:11

Hee Hwang


2 Answers

In general iterators of the class template std::vector are not pointers (though in some early versions of compilers they were implemented as pointers).

For the both calls there will be called the template function. The call of the non-template function requires conversion to const (qualification conversion).

The non-template function would be called if the array was declared with the qualifier const like

const int B[] = {1,2,3,4,5};

On the other hand, if you will declare the vector with the qualifier const like

const vector<int> A = {5,6,7,8,9};

nevertheless the template function will be called because there will be used objects of the type std::vector<int>::const_iterator that are not pointers to constant objects.

like image 60
Vlad from Moscow Avatar answered Dec 01 '25 13:12

Vlad from Moscow


iterator is a set of classes that are used in various containers of the STL. Having this paradigm guarantees that you can use an iterator in template where the container is a template

template<typename Container> is_alone(const Container& c) {
    Container::iterator i = c.begin();
    if(i == c.end())  {
        return false;
    }
    ++i;
    return i == c.end();
}

This snippet above will work whether Container is a std::vector, a std::unordered_map, a std::set, ... How the iterators access the members of a container is left implantation-defined. In concrete terms, a std::vector<T>::iterator will almost always be implemented using a pointer, however this is hidden from the user of a std::vector<T>::iterator, which only needs to know that iterator can be advanced, and can be accessed with operator*.

For you snippet code, the C++ compiler will always target the function with the most specialized argument types that match the concrete argument type you're calling with. Here it is int*, so calling the template by setting It = int*, is more specialized than calling the function with const int*, so the template is preferred.

like image 32
Lærne Avatar answered Dec 01 '25 14:12

Lærne



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!