When I firstly learned about OpenCV with C++, I frequently found a syntax like ‘vector<…>’, ‘list<...>’, and many more that using ‘<...>’. I had no idea what they were, and just continued to learn about using OpenCV libraries. Then when a problem was getting more complex about the ‘...<..>’ syntax (that is called by STL) I realized that I had to know more about this stuff. Therefore, in this case it is important that not only to learn just about particular libraries and their rules, but also to learn about the language facilities and their rules.

So, What is this ‘Container’?
In the past, compiler vendors and many third-party developers offered libraries of container classes to handle the storage and processing of data. Now, C++ standard includes its own built-in container class library, called Standard Template Library (STL).

The STL contains several kinds of entities, the three most important are:
  • Container: is a way that stored data is organized in memory,
  • Algorithms: STL procedures applied to containers to process data in various way, and
  • Iterators: are generalization of the concept of pointers.
In this post, our discussion just focuses on the container, and show one example of it: a vector. In STL it falls into two main categories: they are sequence and associative. These are some example of them:
  • Sequence container: vector, list, and deque.
  • Associative container: set, multiset, map, and multimap.
As said before, our example code and discussion just focus on a vector<>. So what is a vector<>?
Vectors can be thought as smart arrays that they manage the size of storage as a user inserts or deletes data. In other words, vectors can be used much like array since a random access operator “[]” can be used along with them. Note that a random access is fast with vector compared to those containers that support random access operator. But of course they have their own unique features.

Here is a simple code example for the explanation makes more sense:
#include <iostream>
#include <vector>
using namespace std;

int main()
{
   vector<int> coin;
   coin.push_back(120);
   coin.push_back(300);
   coin.push_back(92930);

   unsigned int c_size = coin.size(); //size of coin

   for(unsigned i=0;i<c_size;++i)
      cout<<coin[i]<<' ';

   cout<<endl;

   vector<Time> sumTimeAll;
   sumTimeAll.push_back(Time(1,30));
   sumTimeAll.push_back(Time{2,45});
   sumTimeAll.push_back({1,35});

   Time sumOfTime;
   for(const Time &iter : sumTimeAll)
      sumOfTime = sumOfTime + iter;
   cout<<sumOfTime;

   return 0;
}

The aim of the code is just want to show about how to use vector containers using built-in type i.e., int, and user-defined type i.e., Time. For the first lines on the code is:
vector<int> coin;
coin.push_back(120);
The first line is the definition of coin variable. It is a coin container with an int type. The second line is where we set value on the container, or simply the container now is filled with something-int. It is done with a member function of vector: push_back(). This is where a memory management is tackled by vector<>; The coin size will increase as many as value we ‘push’ into it.

The next line simply gets the size (or sum of the elements ‘pushed’ into it) of the coin. The size() member function of vector is used:

unsigned int c_size = coin.size(); //size of coin
for(unsigned i=0;i<c_size;++i)
      cout<<coin[i]<<' ';
Now lets look at the following line; for() loop:
this for() loop simply prints all values / content of the container coin using random access operator ‘[]’. it prints contents based on its index which start from zero.

For the next following lines are just for comparison for using built-in type and user-defined type. On this example, I take a class or simply a type from the previous article:

The first lines of the code has the same pattern as the example above with int-type:
vector<Time> sumTimeAll;
sumTimeAll.push_back(Time(1,30));
sumTimeAll.push_back(Time{2,45});
sumTimeAll.push_back({1,35});
As seen on the three ways of ‘pushing’ object (or value-type), they are the same. But one thing needed to note here that we cannot directly write:
sumTimeAll.push_back(1,35); //exert error
without ‘{}’ between the value assigned / passed. They are at least two reasons: first, the push_back() of member function only provides one argument passed into it, and the second one is the user-defined type Time has its own constructor pattern we have to follow: so by doing this bellow will also exert error message:
//exert error: there is no constructor with one argument
sumTimeAll.push_back(Time{1}
The next line is also a for() loop like we do with int-type (built-in type) like above example, but with a bit different syntax:
Time sumOfTime;
for(const Time &iter : sumTimeAll)
   sumOfTime = sumOfTime + iter;
cout<<sumOfTime; //output the sum of the time
firstly, the instance of Time class is declared, sumOfTime. This variable is later used to store the sum of time we are going to add / sum up. Then let’s see on the following line, that this for() loop is rather different from for() loop before. The syntax is:
for(:)
This is called a range-for-loop because the word range is often used to mean the same as “sequence of elements.” We read for (int x : v) as “for each int x in v ” and the meaning of the loop is exactly like the equivalent loop over the subscripts [ 0:v.size() ). (Bjarne. Stroustrup. Programming Second Edition).

After the sum operation is done (by adding and assigning sumOfTime in each iter iteration), the result is finally printed by:
cout<<sumOfTime; //output the sum of the time
the result of the code is like bellow:
120 300 92930
5 hours, 50 minutes
That is! One of simple example to use container. If you have any question just ask on the comment bellow.