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:
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:
#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.
0 Comments
Post a Comment