Basic Information About STL
Basic Information About STL
STL stands for Standard Template Library. STL is an important part of the C++ development
environment, and if you intend to be a C++ programmer, you should certainly learn how to use it.
What is STL good for? Generally speaking, it provides ready-to-use solutions for many programming
problems. The word “standard” is also meaningful. It means that every C++ compiler is accompanied
by this software package. So, as long as you use STL, your program portability is high (portability of
C++ programs is a huge but unrelated topic).
What problems can we solve with the help of the STL? Many, but not all – otherwise we wouldn’t
need Boost libraries (free and peer-reviewed portable C++ source libraries) and all of the language
improvements.
Containers,
Algorithms.
There are more features in the library, and we’ll explain them later in the course – don’t worry. We
just think that containers and algorithms are most important, and that’s why we’re going to focus on
them first and most extensively.
Containers, or collections, as they are sometimes called, are meant to contain something inside. This
something is various kinds of data. Different types of containers store data in different manners.
This is good, because it allows programmers to choose the best collection for the task they face. We’ll talk
more about this later. The simplest container you can think of is an array, for example:
int a[10];
The array above is of type int . An array is a container which stores elements of the same type, and usually
those elements occupy a continuous area of memory.
Each element is placed one after the other, starting from a certain location in the memory. You can access a
particular element of an array by its index using the [] operator – the square brackets operator.
For example:
a[ 3] = 3;
cout << a[3] << endl;
The last point is not always a limitation; it all depends on the particular array usage scenario.
Improving arrays
Let us think for a while about how to improve our array and remove some of its limitations.
Let’s design a class named Array , which will be our new better array. This class will remove the
first two limitations of the original array: the inability to change the size, and the lack of knowledge of
its size. The class in its basic form might look like the one in the editor.
On the next slide, the newly created class will be put to use.
#include <exception>
#include <iostream>
class Array
int *_array;
public:
_array (0),
_size (size)
if (size > 0)
void
if (_size == 0)
else
tmp[i] = _array[i];
}
delete[]_array;
_array = tmp;
_array[_size++] = value;
void
if (_size == 1)
delete[]_array;
_array = 0;
else
if (i == index)
j--;
continue;
}
tmp[j] = _array[i];
delete[]_array;
_array = tmp;
_size--;
unsigned int
return _size;
int &
std::exception e;
throw
e;
return _array[index];
}
Array::~Array ()
delete[]_array;
Its initial size is set to 10 . The constructor allocates an array of ten elements inside object A .
The second interesting thing is that we use this object in the same way as a regular array – operator[] is
called for access. Such behavior is possible because the class implements operator[] .
The loops illustrated in the code are using the getSize() method to obtain the actual size of
the Array object. This is another improvement over a standard C++ array.
0 1 2 3 4 5 6 7 8 9
output
int
main ()
Array A (10);
{
A[i] = i;
return 0;
Let’s go further. You’ve probably noticed two methods which have not been discussed
yet: add and delItem() . Now we’re going to put them to work. Take a look at the example in the editor.
This is the main() function, which we’ve seen before, with additional code. The code takes advantage of the
methods add and delItem . These two methods allow our new array to grow and shrink as needed. Another
array limitation seems to have been overcome.
The last important modification is related to access control, which is provided inside operator[] . In case a
program tries to access an element by an index which is out of scope, an exception is thrown.
0 1 2 3 4 5 6 7 8 9
10
11
10
output
int
main ()
Array A (10);
A[i] = i;
A.add (100);
return 0;
Of course, the Array class is far from perfect. There’s a lot of other functionality that could be implemented
here. First of all, the class could be created as a template class. It would allow other types than just integer.
Secondly, some performance issues are present in the previous code. But this is just a brief introduction to the
world of containers.
Now let’s take a look at how STL fits into this picture. In order to do that, we’ll rewrite the main() function
using a very basic STL container – a vector .
As you can see, the vector class allows for the same behavior as our handmade Array class. Moreover,
the vector is a template class and can work with basically any type of element. That is a huge advantage.
In this example, we’re using two very common vector methods: push_back() – which adds a new
element to the end of a vector , and pop_back() – this one removes the last element from a vector .
As the Array class, the vector also has operator[] overloaded. And finally, the method size() ,
whose task is rather obvious. This is a vector , in a nutshell, ladies and gentlemen. Let’s see what else can be
found inside the Standard Template Library.
With the introduction of C++11, we can use a very compact way to initialize vector elements – the initializer
list. We’ll present it here shortly; it’s just a comma-separated list enclosed in braces:
0 0 1 1 2 2 3 3 4 4 5 5 6 6 7 7 8 8 9 9
10
11
10
output
Sandbox
Code
#include <vector>
#include <iostream>
using namespace std;
int
main ()
{
vector < int >v1 (10);
vector < int >v2 = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 };
for (unsigned i = 0; i < v1.size (); ++i)
{
v1[i] = i;
}
for (unsigned i = 0; i < v1.size (); ++i)
{
cout << v1[i] << " ";
cout << v2[i] << " ";
}
cout << endl;
#include <vector>
#include <iostream>
int
main ()
v1[i] = i;
}
v1.push_back (100);
v1.pop_back ();