in
Richard Eigenmann, 1 Mar 2016
Revised 28 Mar 2016 (Thanks Andreas Gieriet)
vector, list, forward_list, deque, array
set, multiset, map, multimap
queue, priority_queue, stack
pair, tuple
See Stroustroup, Programming Principle and Practice Using C++ 20.10
An STL sequence is what is usually called “half-open”; that is, the element identified by begin is part of the sequence, but the end iterator points one beyond the end of the sequence.
See Stroustroup, Programming Principle and Practice Using C++ 20.3
Thanks Andreas Gieriet
#include <vector>
#include <iostream>
int main() {
std::vector <int> myIntVector { 1, 4, 8 };
for( int i=0; i < myIntVector.size(); ++i ) {
std::cout << myIntVector[i] << " ";
}
return 0;
}
Output: 1 4 8
Sample1
From http://www.cprogramming.com/tutorial/stl/iterators.html
#include <vector>
#include <iostream>
int main() {
std::vector<int> myIntVector { 1, 4, 8 };
std::vector<int>::iterator it;
for ( it = myIntVector.begin(); it != myIntVector.end(); ++it ) {
std::cout << *it << " ";
}
return 0;
}
Output: 1 4 8
Sample2
From http://www.cprogramming.com/tutorial/stl/iterators.html
#include <vector>
#include <iostream>
int main() {
std::vector <int> myIntVector { 1, 4, 8 };
//std::vector<int>::iterator it
for (auto it = myIntVector.begin(); it != myIntVector.end(); ++it)
{
std::cout << *it << " ";
}
return 0;
}
Output: 1 4 8
Sample4
#include <vector>
#include <iostream>
int main() {
std::vector <int> myIntVector { 1, 4, 8 };
//std::vector <int>::reverse_iterator it;
for (auto it=myIntVector.rbegin(); it!=myIntVector.rend(); ++it)
{
std::cout << *it << " ";
}
return 0;
}
Output: 8 4 1
Note the rbegin and rend!
Sample3
From http://www.cprogramming.com/tutorial/stl/iterators.html
#include <vector>
#include <iostream>
int main() {
std::vector <int> myIntVector { 1, 4, 8 };
for ( const auto& element : myIntVector ) {
std::cout << element << " ";
}
return 0;
}
Output: 1 4 8
The range-for-loop is defined in terms of begin() and end() functions returning iterators to the first and one beyond the end of our vector elements. The range-for-loop is simply “syntactic sugar” for a loop over a sequence using iterators.
Depeding on the use case: auto element or auto& element or const auto& element.
Sample5
it1 == it2 | true if and only if it1 and it2 point to the same element or both point to one beyond the last element |
it1 != it2 | the revers of the above |
*it1 | refers to the element(object) pointed to by iterator it1 |
var = *it1 | reads the element pointed to by it1 into the variable var |
*it1 = var | writes the variable var into the element pointed to by it1 |
++it1 | advance the iterator to the next element in the sequence or one beyond the last element |
#include <vector> <cr> #include <list> <cr> #include <iostream>
using namespace std;
template<typename Iterator>
Iterator high(Iterator first, Iterator last) {
Iterator high = first;
for (Iterator it = first; it != last; ++it)
if (*high < *it) high = it;
return high;
}
int main() {
vector <int> myVec { 1, 4, 8 };
list <int> myList { 10, 4, 8 };
cout << "myVec high: "<<*high(myVec.begin(),myVec.end()) << endl;
cout << "myList high: "<<*high(myList.begin(),myList.end())<<endl;
return 0;
}
For a better way check out Algorithms in the next chapter!
FindHigh
Bjarne explains why vectors usually perform better: Video (7:45)
(Lists perform better for insertion and removal of elements but the linear search to get to the element dwarfs the vectors' move operation which performs well with modern caches.)
Iterator q is has become invalid
No problems with Iterator q
See: Wikipedia
The lines are kept in a list and the characters of the line in a vector. This allows easy insertion of new lines without having to copy huge blocks of text. Also, iterators pointing at specific lines will be unaffected by the insert or delete operations on other lines.
Run a timing experiment to compare the performance of using a vector versus a list.
(Timing code from 26.6.1 on slide below).
Generate N random int values in the range [0:N).
As each int is generated, insert it into a vector
Plot the results and find the point where one container is more performant than the other. Explain the result and then watch Bjarne's video (7:45)
#include <chrono>
#include <iostream>
#include <vector>
using namespace std::chrono;
void do_something() {
std::vector<int> pointless {0,1,2,3,4,5};
}
int main() {
int n = 10000000;
auto startTime = system_clock::now();
for (int i = 0; i < n; i++) // timing loop
do_something();
auto endTime = system_clock::now();
auto ms = duration_cast<milliseconds>(endTime - startTime).count();
std::cout << "do_something() " << n << " times took "
<< ms << "ms" << std::endl;
}
try on ccp.sh