I have been programming in C++ since 2011. But till today, doubly linked lists, hash tables, pointers and the various searching/sorting algorithms on them have intimidated me. I always had to look at their syntax when I came back to C++ after programming in any other language for a long time. This was a reason I always tried to avoid C++ whenever an alternative is available. But, truth be told, C++ is one of the most powerful and efficient language out there. It is the mother of many other languages for the same reason.
One of the major additions to the C++ language is STL. Let’s know a bit more about STL.
What is STL?
STL stands for Standard Template Library. It is a software library for C++ which has 3 components:
1. Containers – objects that store data (like you store data in an array)
2. Iterators – pointers to traverse through the containers (like you use array index to iterate through an array)
3. Algorithms – pre defined methods for searching/sorting the data in the containers
What’s the big deal about STL?
Imagine overloading the same method 3 times to accommodate 3 different data types. STL is based on the idea of generic programming, i.e. writing one algorithm/method that caters to all the data types. This leads to a massive decrease in the lines of code written.
Also, STL has a readymade set of common data types like arrays, hash tables, linked lists etc. The programmer does not need to write his/her own class/methods to handle the common data structures. It also handles memory leakages, destructors etc. that usually distracts the programmer from the primary code to be written.
STL can be used with any built-in or user defined data type.
What makes STL so powerful and efficient?
The STL implements generic programming through the use of templates. Using templates provides compile-time polymorphism that is often more efficient than traditional run-time polymorphism. If you don’t understand the above terms, refer to the previous article in the series – Templates and their Importance in C++.
Containers in STL
Containers are objects that store data. There are multiple types of containers. The 2 most widely used are – Sequential Containers and Associative Containers.
These containers store data in a sequence. Like you used to store data in an array. We will be discussing 2 sequential containers: vector and list.
A vector is nothing but a resizable array. When you initialized an array, you had to declare its size explicitly. There’s no such need in vectors. Let’s see a bit of code to know more about vectors.
First of all, we need to declare the header file:
Then, in the main function we create the vector that we will be using:
Here, the type of vector is integer. The name of the vector is v. You can see, we didn’t give any size to the vector. Now to insert an element to the vector, we will use the push_back() method.
push_back() inserts and element to the vector. (You can think of it as an alternative for v[index]=1, as we did in arrays)
Let us push 2 more elements in the vector.
We can also use the assignment operator (=) to modify values inside a vector. For eg.
v = 4 // will change the second element of the vector from 2 to 4
But, be careful, you may refer to an index that has not been created yet. That can lead to errors.
Now, you may ask, how can we check the number of elements currently inside a vector, i.e. size of a vector? We have a method for that too. Can you guess what the name of the method is? Yes you got it right, the name is size() .
cout << v.size() << endl;
The above line will output 3, as we have inserted 3 elements till now in the vector.
Now, you may also want to display the elements of the vector. There are better methods to display the elements(hint: iterators) , but for now, we will use our good old for loop for it.
Now, what if we want to check whether the vector is empty or not? There’s a function for this specific purpose too. It’s called empty() (for obvious reasons).
It gives output 1 (true) if the vector is empty, else, 0 (false). You would say that we could just check if size() == 0 or not. Well, in this case, the size of the vector has to be calculated just to check whether it is empty or not. That will take O(n) time. It’s better to use the empty() function as it has been made for the exact purpose.
Accessing elements inside a vector is also easy. You can just refer to them by index , for eg. v.
Here’s the complete source code for a vector:
using namespace std;
// initializing vector
cout<<"before inserting elements, empty(): "<<v.empty()<<endl;
cout<<"after insertion, empty(): "<<v.empty()<<endl;
cout << "size: "<<v.size() << endl;
cout<<"after clear, empty(): "<<v.empty();
The second last line of the above code has a function clear(). Run the above code to see what it does and tell your answer in the comments below.
We will look at the other 2 containers in the next post.