-7

I am using a for-loop to access and print values in a vector (v). The for-loop uses a random access iterator variable starting from v.beginning and and ending before v.end.

#include<iostream>
#include<vector>

using namespace std;



int main(){

 vector<int> v;
       /* create initializer list */
       auto inList = {1, 2, 3, 4, 5}; 
//EDIT
//Works
vector<int> vect1;
vect1.assign(5,100);

for(auto it=vect1.begin(); it<vect1.end();it++){

        cout<<*it<<endl;
    }


//Works
for(auto it=v.begin(); it!=v.end();it++){

    cout<<*it<<endl;
}


return 0;

// Edit: seems to work now.

for(auto it=v.begin(); it<v.end();it++){

    cout<<*it<<endl;
}

// Doesn't Work (ERROR MARKERS Correspond to the following loop)
for(int it=v.begin(); it!=v.end();it++){

    cout<<*it<<endl;
}

return 0;

}

Observation: When i try to change the type from 'auto' to 'int', i receive the following error:

- mismatched types 'const std::reverse_iterator<_Iterator>' and 'int'
    - mismatched types 'const std::fpos<_StateT>' and 'int'
    - mismatched types 'const std::pair<_T1, _T2>' and 'int'
    - cannot convert 'std::vector<int>::iterator {aka __gnu_cxx::__normal_iterator<int*, std::vector<int> >}' to 'int' in initialization
    - no match for 'operator!=' (operand types are 'int' and 'std::vector<int>::iterator {aka __gnu_cxx::__normal_iterator<int*, 
     std::vector<int> >}')
    - mismatched types 'const __gnu_cxx::__normal_iterator<_IteratorL, _Container>' and 'int'
    - mismatched types 'const __gnu_cxx::__normal_iterator<_Iterator, _Container>' and 'int'
    - mismatched types 'const std::vector<_Tp, _Alloc>' and 'int'
    - mismatched types 'const __gnu_cxx::new_allocator<_Tp>' and 'int'
    - mismatched types 'const std::istreambuf_iterator<_CharT, _Traits>' and 'int'
    - mismatched types 'const _CharT*' and 'int'
    - mismatched types 'const std::__cxx11::basic_string<_CharT, _Traits, _Alloc>' and 'int'
    - mismatched types 'const std::allocator<_CharT>' and 'int'
    - mismatched types 'const std::move_iterator<_Iterator>' and 'int'

Also, when i revert to change the type of the 'it' variable to 'auto' and change the stopping condition of the for loop from '!=' to < then it doesn't work, although cpp reference says that the "<" operator it is supported.

Questions

1) Why does my iterator variable have to be type 'auto' for the .begin() and .end() functions?

2) why cant i use '<' logical operator with the iterator variable?

EmptyStack
  • 27
  • 8
  • 5
    *"When i try to change the type from 'auto' to 'int', i receive the following error:"* `std::vector::iterator` is not `int`. What would you expect `*it` to do if `it` was `int`? – François Andrieux Jul 31 '17 at 17:12
  • 1
    Please provide [mcve]: 1) errors provided doesn't match the code. 2) What's `v`? 3) Yes, you can use `std::vector::iterator` instead of `auto`. – Algirdas Preidžius Jul 31 '17 at 17:14
  • but random access iterators have pointer functionality. You can get a pointer with return type int. – EmptyStack Jul 31 '17 at 17:15
  • The 2nd example (`for(auto it = v.begin(); it < v.end(); it++)`) works fine for me when `v` is `std::vector`. What is `v`? The fact that the error message speaks of `std::reverse_iterator` suggests that there is more at work here than you are showing. – François Andrieux Jul 31 '17 at 17:15
  • @TheAce If they provide pointer-like functionality, it doesn't mean that they are pointers. – Algirdas Preidžius Jul 31 '17 at 17:16
  • @TheAce An `int` is not an iterator. An `int*` is a kind of iterator, and it's possible that `std::vector::iterator` is a typedef for `int*` but it doesn't have to be. Either way using `int` is wrong. – Kevin Jul 31 '17 at 17:16
  • Thanks for your replies. Vector v, is intialized using auto intializer list: auto inList={1,2,3,4,5}; – EmptyStack Jul 31 '17 at 17:29
  • Thanks for your replies. Vector v, is intialized using auto intializer list: auto inList={1,2,3,4,5} but was declared with return type 'int'. The following error also shows when i initialise vector v with 5 integers using the .assign() function and using an iterator of type int* instead of 'int.... error marker: cannot convert 'std::vector::iterator {aka __gnu_cxx::__normal_iterator >}' to 'int*' in assignment. – EmptyStack Jul 31 '17 at 17:35
  • @TheAce Please [edit] your question to add all the relevant information. – Algirdas Preidžius Jul 31 '17 at 17:45
  • @ François Andrieux thankyou . I also got it to work also by assigning 5 integers to the vector instead of using an initialiser list of numbers (of type auto). But why auto ?? I ask for knowledge and c++ reference or other sources don't making this clear imo. – EmptyStack Jul 31 '17 at 17:45
  • @TheAce 1) I already mentioned that you could use `std::vector::iterator` (if you are, indeed, using `std::vector`) instead of `auto`. 2) how don't c++ references make it clear? Documentations like theses are primary source of information on library functions/classes. If they are not clear to you, consider reading [good C++ book](https://stackoverflow.com/questions/388242/the-definitive-c-book-guide-and-list). SO is not a tutorial site. – Algirdas Preidžius Jul 31 '17 at 17:48
  • @Algirdes Preidzius. Thankyou for your suggestions. I did not intend to use this site in this way. Using c++ reference did not answer these specific question directly or perhaps it did, more subtly but i could have missed the information. C++ Reference gave me a definitive answer for my second question but , i received errors on my code which i now fixed. Q1 is yet to be answered. – EmptyStack Jul 31 '17 at 18:08

1 Answers1

2

You don't have to use auto if you don't want to, but you can of course.

The type returned by std::vector<int>::begin() and std::vector<int>::end() is a std:vector<int>::iterator (or std:vector<int>::const_iterator, depending on context), it is not an int. You could as well have written this instead:

for(vector<int>::iterator it=vect1.begin(); it<vect1.end();it++){
    cout<<*it<<endl;
}

or

for(vector<int>::const_iterator it=vect1.begin(); it<vect1.end();it++){
    cout<<*it<<endl;
}

In either case, you don't want to modify the contents of the vector. Regarding your examples:

  • The first for-loop is fine and works. I've never seen anyone use the < operator for this, rather !=.

  • The second for-loop does also work, but does nothing, as v is empty.

  • The third for-loop is nonsense, as pointed out, an iterator is returned by begin() and end(), not an integer. To access the data the iterator points to, you need to de-reference it with the * operator, as you do for the output.

Hope this helps.

Edit: One more thing. In C++, it is also advisable to use ++it instead of it++, in general for all increments in for loops.

Here is a short explanation:

++i or i++ in for loops ??

Remy Lebeau
  • 555,201
  • 31
  • 458
  • 770
Hans Hohenfeld
  • 1,729
  • 11
  • 14
  • No. Iterators a distinct types. The auto keyword just enables type deduction, the compiler "knows" the right type and places it instead of auto. Details on auto can be found i.e. here: http://en.cppreference.com/w/cpp/language/auto – Hans Hohenfeld Jul 31 '17 at 18:16
  • Thankyou issue resolved. I understood that part about auto. I was under the impression that an iterator worked like a pointer but for vectors (Containers) after i misinterpret this sentence: "Random-access iterators are iterators that can be used to access elements at an arbitrary offset position relative to the element they point to, offering the same functionality as pointers". Source: http://www.cplusplus.com/reference/iterator/RandomAccessIterator. – EmptyStack Jul 31 '17 at 18:29
  • An iterator works much like apointer, but its isn't one. It is an object encapsulating a pointer and providing some abstraction and functionality. On the site you've linked, there is actually an example, how an iterator could be implemented: http://www.cplusplus.com/reference/iterator/iterator/ - see the example on the bottom of the page – Hans Hohenfeld Jul 31 '17 at 18:43
  • A pointer is one type of iterator. An iterator is not necessarily a pointer. For a `std::vector`, the iterator type (returned by `begin()`) CAN be a pointer, but doesn't need to be. For some other containers, like `std::list`, the iterators are less likely to be pointers (since iterating the iterator produces an iterator that references the "next" element in the list, which is not necessarily adjacent in memory). – Peter Jul 31 '17 at 21:24