pragma
#pragma once
used to remove the duplicate header files (if included), during a compilation.
- NOTES:
set
- M-1: paramterized constructor: E.g.
Test(int n): a(n) {}
- M-2: create a set func: E.g.
set_var(int a)
- M-1: paramterized constructor: E.g.
get
- M-1: create a set func: E.g.
get_var() {return a}
- M-1: create a set func: E.g.
View code:
#include <iostream>
class Test
{
int a;
public:
// default constructor
Test() {
a = 0;
}
// parameterized constructor
Test(int n) {
a = n;
}
// copy constructor
Test (Test& obj){
a = obj.a;
}
void print() {
std::cout << a << std::endl;
}
};
int main() {
Test A(10), B(20);
A.print();
B.print();
// =================================
A = Test(B);
A.print();
B.print();
return 0;
}
- define:
- Vectors are same as dynamic arrays with the ability to resize itself automatically when an element is inserted or deleted, with their storage being handled automatically by the container.
- Vector elements are placed in contiguous storage so that they can be accessed and traversed using iterators.
NOTE:
- In vectors, data is inserted at the end.
- Inserting at the end takes differential time, as sometimes there may be a need of extending the array.
- Removing the last element takes only constant time because no resizing happens.
- Inserting and erasing at the beginning or in the middle is linear in time.
- Certain functions associated with the vector are:
- Iterators
begin()
– Returns an iterator pointing to the first element in the vectorend()
– Returns an iterator pointing to the theoretical element that follows the last element in the vectorrbegin()
– Returns a reverse iterator pointing to the last element in the vector (reverse beginning). It moves from last to first elementrend()
– Returns a reverse iterator pointing to the theoretical element preceding the first element in the vector (considered as reverse end)cbegin()
– Returns a constant iterator pointing to the first element in the vector.cend()
– Returns a constant iterator pointing to the theoretical element that follows the last element in the vector.crbegin()
– Returns a constant reverse iterator pointing to the last element in the vector (reverse beginning). It moves from last to first elementcrend()
– Returns a constant reverse iterator pointing to the theoretical element preceding the first element in the vector (considered as reverse end)*size
- Capacity
size()
– Returns the number of elements in the vector.max_size()
– Returns the maximum number of elements that the vector can hold.capacity()
– Returns the size of the storage space currently allocated to the vector expressed as number of elements.resize(n)
– Resizes the container so that it contains ‘n’ elements.empty()
– Returns whether the container is empty.shrink_to_fit()
– Reduces the capacity of the container to fit its size and destroys all elements beyond the capacity.reserve()
– Requests that the vector capacity be at least enough to contain n elements.*push_back()
- Element access
reference operator [g]
– Returns a reference to the element at position ‘g’ in the vectorat(g)
– Returns a reference to the element at position ‘g’ in the vectorfront()
– Returns a reference to the first element in the vectorback()
– Returns a reference to the last element in the vectordata()
– Returns a direct pointer to the memory array used internally by the vector to store its owned elements.
- Modifiers
assign()
– It assigns new value to the vector elements by replacing old onespush_back()
– It push the elements into a vector from the backpop_back()
– It is used to pop or remove elements from a vector from the back.insert()
– It inserts new elements before the element at the specified positionerase()
– It is used to remove elements from a container from the specified position or range.swap()
– It is used to swap the contents of one vector with another vector of same type. Sizes may differ.clear()
– It is used to remove all the elements of the vector containeremplace()
– It extends the container by inserting new element at positionemplace_back()
– It is used to insert a new element into the vector container, the new element is added to the end of the vector
- Iterators
- insert at random position by iterator (position)
- display all the elements Example code
// M-1
for (std::vector<int>::iterator i = v1.begin(); i != v1.end(); ++i)
{
std::cout << *i << std::endl;
}
// M-2
for (int i = 0; i < v1.size(); ++i)
{
std::cout << v1[i] << std::endl;
// std::cout << v1.at(i) << std::endl;
}
- define:
- Lists are sequence containers that allow non-contiguous memory allocation.
- As compared to vector, list has slow traversal, but once a position has been found, insertion and deletion are quick.
- Normally, when we say a List, we talk about doubly linked list.
- For implementing a singly linked list, we use forward list.
- Functions used with List:
front()
– Returns the value of the first element in the list.back()
– Returns the value of the last element in the list .push_front(g)
– Adds a new element ‘g’ at the beginning of the list .push_back(g)
– Adds a new element ‘g’ at the end of the list.pop_front()
– Removes the first element of the list, and reduces size of the list by 1.pop_back()
– Removes the last element of the list, and reduces size of the list by 1list::begin()
andlist::end()
in C++ STL– begin() function returns an iterator pointing to the first element of the listend()
– end() function returns an iterator pointing to the theoretical last element which follows the last element.- list
rbegin()
andrend()
function in C++ STL– rbegin() returns a reverse iterator which points to the last element of the list. rend() returns a reverse iterator which points to the position before the beginning of the list. - list
cbegin()
andcend()
function in C++ STL– cbegin() returns a constant random access iterator which points to the beginning of the list. cend() returns a constant random access iterator which points to the end of the list. - list
crbegin()
andcrend()
function in C++ STL– crbegin() returns a constant reverse iterator which points to the last element of the list i.e reversed beginning of container. crend() returns a constant reverse iterator which points to the theoretical element preceding the first element in the list i.e. the reverse end of the list. empty()
– Returns whether the list is empty(1) or not(0).insert()
– Inserts new elements in the list before the element at a specified position.erase()
– Removes a single element or a range of elements from the list.assign()
– Assigns new elements to list by replacing current elements and resizes the list.remove()
– Removes all the elements from the list, which are equal to given element.list::remove_if()
in C++ STL– Used to remove all the values from the list that correspond true to the predicate or condition given as parameter to the function.reverse()
– Reverses the list.size()
– Returns the number of elements in the list.list resize()
function in C++ STL– Used to resize a list container.sort()
– Sorts the list in increasing order.- list
max_size()
function in C++ STL– Returns the maximum number of elements a list container can hold. list unique()
in C++ STL– Removes all duplicate consecutive elements from the list.list::emplace_front()
andlist::emplace_back()
in C++ STL– emplace_front() function is used to insert a new element into the list container, the new element is added to the beginning of the list. emplace_back() function is used to insert a new element into the list container, the new element is added to the end of the list.list::clear()
in C++ STL– clear() function is used to remove all the elements of the list container, thus making it size 0.list::operator=
in C++ STL– This operator is used to assign new contents to the container by replacing the existing contents.list::swap()
in C++ STL– This function is used to swap the contents of one list with another list of same type and size.- list
splice()
function in C++ STL– Used to transfer elements from one list to another. - list
merge()
function in C++ STL– Merges two sorted lists into one - list
emplace()
function in C++ STL– Extends list by inserting new element at a given position.*size
- insert at random position by value
- display all the elements
- assign elements as per boost assign Example code
std::list<int> l1 = list_of(1) (21) (34) (55) (67);
std::list<int>::iterator it = l1.begin();
advance(it, 2); // now positioned to '34'
advance(it, -1); // now positioned to '21'
std::cout << *it << std::endl; // '21'
// display the output
for (std::list<string>::iterator i = l1.begin(); i != l1.end(); ++i)
{
std::cout << *i << std::endl;
}
- define:
- Double ended queues are sequence containers with the feature of expansion and contraction on both the ends.
- They are similar to vectors, but are more efficient in case of insertion and deletion of elements. Unlike vectors, contiguous storage allocation may not be guaranteed.
- Double Ended Queues are basically an implementation of the data structure double ended queue.
- A queue data structure allows insertion only at the end and deletion from the front.
- This is like a queue in real life, wherein people are removed from the front and added at the back.
- Double ended queues are a special case of queues where insertion and deletion operations are possible at both the ends.
- Functions used with Deque:
- The functions for deque are same as vector, with an addition of
push
andpop
operations for both front and back.
- The functions for deque are same as vector, with an addition of
size
push_front()
push_back()
push_back()
pop_back()
- insert at random position by iterator (position)
push_front
(from boost lib) Example coding- access elements
d1.front().first == "laxman"
ord1[0].first == "laxman"
- access elements
// PREVIEW
std::deque<pair_type> d1;
push_front(d1) ("ram", "sita") ("abhi", "adi") ("laxman", "kalki");
...
...
// display the output
for(auto& [key, val] : d1) {
std::cout << "key = " << key << ", val = " << val << std::endl;
}
-
define:
-
A stack is a container adapter. It's sole purpose is to take some other type of container (a std::deque by default) and restrict the visible interface to that container to the few operations allowed for a stack. Among other things, that means that the only element in a stack that you can observe is the top.
-
If you need to observe other elements being stored, then you don't want to use a stack. The most obvious choice is to use a std::deque (or std::vector) directly. When you need stack-like access, you can use push_back, back and pop_back to get it. When you need access to internal elements, you can use begin(), end(), operator[], at(), etc., to get that.
-
-
size
-
top
-
push
-
pop
-
can't be inserted at a position. Basically, all the elements are stacked one over the other.
-
display all the elements
- assign using boost lib Example code
// PREVIEW
std::stack<string> s1 = list_of("abhi") ("adi") ("victor") ("shyam")
while(!s1) {
std::cout << s1.top() << std::endl;
s1.pop()
}
> NOTE:
> - `deque` is best sequence container out of all. <br/>
> - "Memory is allocated differently for vectors and queues. A vector always occupies a contiguous region of memory. If a vector grows too large, it may need to be moved to a new location where it will fit. A deque, on the other hand, can be stored in several non-contiguous areas; it is segmented. A member function, capacity(), returns the largest number of elements a vector can store without being moved, but capacity() isn’t defined for deques because they don’t need to be moved." <--- as quotes in __Book: OOP in C++__
- define: Sets are a type of associative containers in which each element has to be unique, because the value of the element identifies it.
NOTE:
- The value of the element cannot be modified once it is added to the set,
- though it is possible to remove and add the modified value of that element.
- Some basic functions associated with Set:
begin()
– Returns an iterator to the first element in the set.end()
– Returns an iterator to the theoretical element that follows last element in the set.size()
– Returns the number of elements in the set.max_size()
– Returns the maximum number of elements that the set can hold.empty()
– Returns whether the set is empty.
- a list of keys (of any type: int, string)
- print all the elements Example code. Here is a preview:
std::set<int> s1 = {1, 2, 3};
for (std::set<int>::iterator i = s1.begin(); i != s1.end(); ++i)
{
std::cout << *i << std::endl;
}
- access each element by position
std::set<int>::iterator = s1.begin()
advance(it, 2) // set at position 2 i.e 3rd element
- define: similar to set, with an exception that multiple elements can have same values.
- Some Basic Functions associated with multiset:
begin()
– Returns an iterator to the first element in the multisetend()
– Returns an iterator to the theoretical element that follows last element in the multisetsize()
– Returns the number of elements in the multisetmax_size()
– Returns the maximum number of elements that the multiset can holdempty()
– Returns whether the multiset is empty
- define: Each element has a key value and a mapped value.
NOTE: No two mapped values can have same key values.
- Some basic functions associated with Map:
begin()
– Returns an iterator to the first element in the mapend()
– Returns an iterator to the theoretical element that follows last element in the mapsize()
– Returns the number of elements in the mapmax_size()
– Returns the maximum number of elements that the map can holdempty()
– Returns whether the map is emptypair insert(keyvalue, mapvalue)
– Adds a new element to the maperase(iterator position)
– Removes the element at the position pointed by the iteratorerase(const g)
– Removes the key value ‘g’ from the mapclear()
– Removes all the elements from the map
insert
(from boost lib) Example code- display the output
// PREVIEW
for (auto& [key, val] : map_var) {
std::cout << "key = " << key << ", val = " << val << std::endl;
}
- define: is just like Map, except for "multiple elements can have same keys".
insert
(from boost lib) Example code- Some Basic Functions associated with multimap:
begin()
– Returns an iterator to the first element in the multimapend()
– Returns an iterator to the theoretical element that follows last element in the multimapsize()
– Returns the number of elements in the multimapmax_size()
– Returns the maximum number of elements that the multimap can holdempty()
– Returns whether the multimap is emptypair<int,int> insert(keyvalue,multimapvalue)
– Adds a new element to the multimap
- a sequence of 2 elements
- Example code 2
std::pair<string, int> p1 = {"abhijit", 102};
p1.first; // abhijit
p1.second; // 102
- a sequence of any number of elements
- Example code 1, Example code 2. Below is a small preview:
std::tuple<string, int, int> t1 = {"abhijit", 102, 2423432};
std::cout << std::get<0>(t1) << std::endl;
std::cout << std::get<1>(t1) << std::endl;
std::cout << std::get<2>(t1) << std::endl;
- each element of 1
- insertion:
std::vector<string> v1 += 1, 2, 33, 45, 64;
std::vector<string> v1 = list_of ("abhijit") ("adi") ("victor")
- access:
- print:
- search:
- insertion:
- each element of pair
- insertion:
std::vector<std::pair<int, string>> v1 = list_of<std::pair<int, string>> (1, "abhijit") (4, "adi") (6, "victor")
std::vector<std::pair<int, string>> v1 = map_list_of (1, "abhijit") (4, "adi") (6, "victor")
- access:
- print:
- search:
- insertion:
- each element of tuple
- insertion:
std::vector<boost::tuple<int, string, int>> v1 = list_of<boost::tuple<int, string, int>> (1, "abhijit", 203) (4, "adi", 204) (6, "victor", 2035)
std::vector<boost::tuple<int, string, int>> v1 = tuple_list_of (1, "abhijit", 203) (4, "adi", 204) (6, "victor", 2035)
- access:
- insertion:
boost::get<0>(v[i]) // 1st tuple val of ith element of vector v
boost::get<1>(v[i]) // 2nd tuple val of ith element of vector v
boost::get<2>(v[i]) // 3rd tuple val of ith element of vector v
- print:
- search:
- List of pair:
- insertion:
std::list<>
- insertion:
- Insertion
- All containers have different insertion/assignment methods:
insert
,list_of
,map_list_of
,+=
,push_front
,push_back
,....
- All containers have different insertion/assignment methods:
- Access
- by array. E.g.
v[i]
- by
at
function. E.g.v.at(i)
- by iterator technique:
*it
- by array. E.g.
std::vector<int> v1;
std::vector<int>::iterator it = v1.begin();
std::advance(it, 2) // from pos: 0 to 2
std::advance(it, -1) // from pos: 2 to 1
std::cout << *it << std::endl;
- Search
- by algorithm:
find
- by algorithm:
Sometimes we want to express the state of “nothing meaningful” instead of a value. This is the use case for C++17’s std::optional.
In programming, we often come across the situation that there is not always a concrete value for something. For example, give me the first even number in a text, if there is any. If not, that’s fine. Or a class has an optional member, i.e. one that does not always need to be set.
In older code, these situations typically are solved by either “magic values” or null pointers. A magic value could be, for example, an empty string, or 0 or -1 or a maximum unsigned value, like std::string::npos.
Both approaches have their drawbacks: A magic value artificially constrains the range of values available. It is also only by convention distinguishable from valid, normal values. For some types, there are no obvious magic values, or values cannot be created in a trivial manner. A null pointer to denote no value means, that valid values have to be allocated somewhere, which is either a costly operation or difficult to implement.
- Quickstart:
#include <optional>
int main() {
std::optional<int> i; // No need to initialize with any value
std::cout << i << std::endl; // nullopt
return 0;
}
- More:
#include <optional>
using std::string;
int main()
{
std::string text = /*...*/;
std::optional<unsigned> opt = firstEvenNumberIn(text);
if (opt.has_value())
{
std::cout << "The first even number is "
<< opt.value()
<< ".\n";
}
}
OR
#include <optional>
using std::string;
int main()
{
std::string text = /*...*/;
std::optional<unsigned> opt = firstEvenNumberIn(text);
if (opt) // using pointer
{
std::cout << "The first even number is "
<< *opt
<< ".\n";
}
}
- Conclusion
std::optional
is a handy, little, but powerful library feature. The next time you try to figure out what the magic value for “nothing” should be, rememberstd::optional
.
- References