Standard Template Library

vector vs. array

Why vector instead of array?

  • Arrays do not support copying wirh =
  • Arrays do not support comparison with ==
  • Arrays do not remember their size
  • Arrays do not check if the index is valid or no

Different ways of initializing vectors:

/*** array initialization ***/
int array[] = {1,2,3,4,5,6,7,8,9,10};

/*** vector initialization ***/
vector<int> v1 {10}; // v1 has size=1, with first element=10
vector<int> v1 (10); // v1 has size=10

string class vs. built-in string

  • Built-in string is simply an array of characters
  • Built-in string has the porblems of arrays

range

int sum = 0;

for (auto x : myvec) { // auto: infer automatic type
   sum += x;
}

Containers

Iterators

  • iterator begin()
  • iterator end()
  • advance the iterator: ++itr or itr++
for(vector<int>::iterator itr = vec.begin(); 
                 itr != vec.end();
                 ++itr) {
    // body of for loop
}

lvalue reference vs. rvalue reference

  • lvalue reference can be used as another name for a variable

lvalue reference:

string str = 'Hello';
string & lstr = str;  // lvalue ref. for str

lstr += ' world!'; // changes str to 'Hello world!'

rvalue reference is declared by &&. It is used to for temporary values, and can also holds things that there is no variable name associated with them. Fr example, if we have an expression as x = y + z, the value of x has a variable name associated with it but there is nothing for a temporary calculation y + z. Therefore, one can create a rvalue reference to hold that temporary calculation

double && rx = y + z; // this is an rvalue-reference

double & x = y + z; // this is invalid assignment

Another example, is using reference to constant objects such as below:

string && rstr = "Hello";

string & lstr = "Hello"; // this is invalid

lvalue reference usages

  • aliasing complicated names

Create a new name for a complicated reference

auto & easyref = myList[ myhash(x+y, mylist.size() ];
  • modifiying elements in range loop

Suppose we intend to increment all the elements of myvec:

for(i=0; i< myvec.size(); ++i)
    ++myvec[i];

Doing this in a range-loop requires using lvalue-reference:

for (auto & x : myvec) 
    ++x;
  • To avoid full copy of large objects

Suppose we have a function findMax() that return the largest element of a vector. If we want to use the largest element of a vector in a new variable as follows, that requires copying that element

auto largestVal = findMax(myvec);

To avoid this copying, we can use lvalue-reference that creates an alias to the largest value, and no need for deep copying:

auto & largestVal = findMax(myvec);

Parameter Passing and Return Passing

Parameter Passing

There are four types of parameter passing:

call-by-value

Requires copying the objects into argument variables:

void calMean(double a, double b);

call-by-reference (call-by-lvalue-reference)

To alter the values of the arguments as output of a function, we need to use references

void swap(double & a, double & b);

call-by-const-reference

In cases when we do not want to alter the input argument, we can use constant reference. Consider the code below:

double getRandomElement(vector<double> vec);

The abovr code requires copying the entire passed vector to vec, exteremely expendive process. Instead, we can avoid that by the following

double getRandomElement(const vector<double> & vec);

this function can be called by

vector<double> x {1.5, 3.5, 2.4};
getRandomElement(x);

call-by-rvalue-reference (C++11)

double getRandomElement(vector<double> && vec);

The above declartion, also allows calling the function as below:

randomVector({1.5, 3.5, 2.4});

Return Passing

Return-by-value

Return-by-const-reference

Return-by-reference

C++11 Big-Five

Destructor

Copy-constructor

Move-assignment

Copy-assignment

Move-assignment

Templates

Function templates

Class template


In [ ]: