Presentation is loading. Please wait.

Presentation is loading. Please wait.

The Standard Template Library

Similar presentations


Presentation on theme: "The Standard Template Library"— Presentation transcript:

1 The Standard Template Library
Lego Blocks Example A brief introduction to the very expansive Standard Template Library (STL)

2 Today’s Questions Why should I use the STL? What is an std::vector?
How can I use an std::vector? How does an std::vector work?

3 Why use the STL? Writing templates can be difficult
Using templates is much easier and more productive E.g. write your own sort function versus use a templated sort function The STL has you covered std::swap std::sort std::pair std::min And so much more!

4 The Containers Library
Several data structures are available std::vector – a dynamic contiguous array of elements of some type std::list – a doubly linked-list some type The data structures are templated std::vector<double> – a dynamic array that stores doubles std::list<std::string> – a linked-list that stores std::strings

5 Motivating std::vector
We want to read integers from the user to an array until EOF <Ctrl+D> Then do some work on the array Problem: How big of an array should we allocate? We won’t know until after all the input is read. Solution: linked list (std::list) But lists are inefficient – accessing an element requires O(n) Better Solution: an array that can grow dynamically (std::vector) Accessing an element requires O(1)

6 Using std::vector – some of its member functions
Accessing elements operator[] – same syntax as a C-style array Inserting new elements push_back(…) Modifying existing elements operator[] – still like a C-style array Querying number of elements size() int value = my_vector[42]; my_vector[42] = 64;

7 Accepting Integer Input into a Vector
#include <iostream> #include <vector> std::vector<int> get_integers(std::istream& stream) { std::vector<int> integers; int value; while(stream >> value) { integers.push_back(value); } return integers; input_to_vector.cpp

8 Accepting Integer Input into a Vector
Include header to use vector #include <iostream> #include <vector> std::vector<int> get_integers(std::istream& stream) { std::vector<int> integers; int value; while(stream >> value) { integers.push_back(value); } return integers; Returns a vector of integers Calls vector’s default constructor: the vector is now empty input_to_vector.cpp

9 Accepting Integer Input into a Vector
#include <iostream> #include <vector> std::vector<int> get_integers(std::istream& stream) { std::vector<int> integers; int value; while(stream >> value) { integers.push_back(value); } return integers; Insert a new int element into the vector. Will grow in size to accommodate new elements. input_to_vector.cpp

10 Printing a Vector’s Elements
int main() { std::vector<int> integers = get_integers(std::cin); for(std::size_type i = 0; i < integers.size(); ++i) { std::cout << integers[i] << " "; } std::cout << "\n"; Use a for loop and print out each element in the vector. Remember that you can use operator[] and size()! input_to_vector.cpp

11 Printing a Vector’s Elements
int main() { std::vector<int> integers = get_integers(std::cin); for(int i = 0; i < integers.size(); ++i) { std::cout << integers[i] << " "; } std::cout << "\n"; input_to_vector.cpp

12 Printing a Vector’s Elements
int main() { std::vector<int> integers = get_integers(std::cin); for(int i = 0; i < integers.size(); ++i) { std::cout << integers[i] << " "; } std::cout << "\n"; int is signed size() returns size_t, which is unsigned Comparing signed and unsigned numbers will cause a compiler warning! input_to_vector.cpp warning: comparison between signed and unsigned integer expressions [-Wsign-compare]

13 Printing a Vector’s Elements… Correctly
int main() { std::vector<int> integers = get_integers(std::cin); for(size_t i = 0; i < integers.size(); ++i) { std::cout << integers[i] << " "; } std::cout << "\n"; input_to_vector.cpp

14 Vector Behind the Scenes
Input: <Ctrl + D> #include <iostream> #include <vector> std::vector<int> get_integers(std::istream& stream) { std::vector<int> integers; int value; while(stream >> value) { integers.push_back(value); } return integers; int * array = int size = 0 int capacity = 3 integers ? Default constructor creates a contiguous array of capacity N input_to_vector.cpp

15 Vector Behind the Scenes
Input: <Ctrl + D> #include <iostream> #include <vector> std::vector<int> get_integers(std::istream& stream) { std::vector<int> integers; int value; while(stream >> value) { integers.push_back(value); } return integers; int * array = int size = 1 int capacity = 3 integers 1 ? A new element is added, so the array is updated. Size increases by one. input_to_vector.cpp

16 Vector Behind the Scenes
Input: <Ctrl + D> #include <iostream> #include <vector> std::vector<int> get_integers(std::istream& stream) { std::vector<int> integers; int value; while(stream >> value) { integers.push_back(value); } return integers; int * array = int size = 2 int capacity = 3 integers 1 3 ? A new element is added, so the array is updated. Size increases by one. input_to_vector.cpp

17 Vector Behind the Scenes
Input: <Ctrl + D> #include <iostream> #include <vector> std::vector<int> get_integers(std::istream& stream) { std::vector<int> integers; int value; while(stream >> value) { integers.push_back(value); } return integers; int * array = int size = 3 int capacity = 3 integers 1 3 8 A new element is added, so the array is updated. Size increases by one. input_to_vector.cpp

18 Vector Behind the Scenes
Input: <Ctrl + D> #include <iostream> #include <vector> std::vector<int> get_integers(std::istream& stream) { std::vector<int> integers; int value; while(stream >> value) { integers.push_back(value); } return integers; int * array = int size = 3 int capacity = 3 integers 1 3 8 ? A new element to add, but capacity == size. Create a new array of capacity 2*size, then copy the old array’s values into it. Delete the old array to avoid memory leaks. input_to_vector.cpp

19 Vector Behind the Scenes
Input: <Ctrl + D> #include <iostream> #include <vector> std::vector<int> get_integers(std::istream& stream) { std::vector<int> integers; int value; while(stream >> value) { integers.push_back(value); } return integers; int * array = int size = 3 int capacity = 3 integers 1 3 8 1 3 8 ? A new element to add, but capacity == size. Create a new array of capacity 2*size, then copy the old array’s values into it. Delete the old array to avoid memory leaks. input_to_vector.cpp

20 Vector Behind the Scenes
Input: <Ctrl + D> #include <iostream> #include <vector> std::vector<int> get_integers(std::istream& stream) { std::vector<int> integers; int value; while(stream >> value) { integers.push_back(value); } return integers; int * array = int size = 3 int capacity = 6 integers 1 3 8 ? A new element to add, but capacity == size. Create a new array of capacity 2*size, then copy the old array’s values into it. Delete the old array to avoid memory leaks. input_to_vector.cpp

21 Vector Behind the Scenes
Input: <Ctrl + D> #include <iostream> #include <vector> std::vector<int> get_integers(std::istream& stream) { std::vector<int> integers; int value; while(stream >> value) { integers.push_back(value); } return integers; int * array = int size = 4 int capacity = 6 integers 1 3 8 7 ? Add new element to array. Size increases by one. input_to_vector.cpp

22 Vector Behind the Scenes
Input: <Ctrl + D> #include <iostream> #include <vector> std::vector<int> get_integers(std::istream& stream) { std::vector<int> integers; int value; while(stream >> value) { integers.push_back(value); } return integers; int * array = int size = 5 int capacity = 6 integers 1 3 8 7 2 ? A new element is added, so the array is updated. Size increases by one. input_to_vector.cpp

23 Vector’s Algorithmic Complexity
Efficiently add elements with push_back() When there isn’t enough space, capacity grows (usually by 2x) So, even for a large number of N, push_back() will only generate a few array copies On average push_back() has O(1) complexity

24 Vector’s Different Constructors
std::vector<int> vec1; // default constructor. size = 0 std::vector<int> vec2(10); // size = 10, values unspecified std::vector<int> vec3(10, -1); // size = 10, all values -1 vector_constructors.cpp

25 Vectors Versus C-Style Arrays
int * a = new int[10]; int * b = new int[10]; std::vector<int> v1(10), v2(10); // access elements the same way a[0] = 5; v1[0] = 5; // creating copies a = b; v1 = v2; // destroying delete [] a; delete [] b; What happens when a = b? Shallow copy – memory leak! What happens when v1 = v2? Deep copy – v2’s elements are copied to v1 Do we need to delete v1 and v2? No, they are not pointers std::vector has a destructor, it will clean up after itself Tip: avoid pointers, let std::vector manage memory for you. vector_versus_arrays.cpp

26 Bounds Checking with Vectors
operator[] does not create values operator[] does not check bounds Out-of-bounds indices will cause your program to crash! For the milestones, you can use DebugCheck to do bounds checking It will (also) make your program run more slowly std::vector<int> v1; // size 0 v1.push_back(-3); // size 1 v[0] = -2; // replace -3 with -2 v[1] = 5; // ? vector_bounds_checking.cpp

27 Vector’s Algorithmic Complexity
Efficient random access to data with operator[] Internally, the vector stores a contiguous data array Accesses have O(1) complexity

28 Learning More About C++ and the STL
Books Problem Solving in C++, Chapter 18 (Walter Savitch) C++ Primer, Lippman, Lajoie, and Moo Online Google


Download ppt "The Standard Template Library"

Similar presentations


Ads by Google