Learning to be Giant.

C++ Learning Notes II


This is the second article in this series. Most contents are excerpted from C++ Primer, 5th edition, click to purchase from Amazon.

List Initialization

The following are valid initialization:

int units_sold = {0};
int units_sold = 0;
int units_sold(0);
int units_sold{0};

List initialization does not allow conversions which loses precision:

long double ld = 3.1415926;
int a{ld}, b={ld}; // error
int c(ld), d=ld; //ok

List initialization can be used to initialize vectors:

vector<string> v1 = {"a", "an", "the"}; //ok
vector<string> v1{"a", "an", "the"}; //ok
vector<string> v1("a", "an", "the"); //error

Ways to initialize a vector

This is extracted from C++ Primer, 5th edition ||| —|—-|— |vector<T> v1|v1 is empty. default initialization| |vector<T> v2(v1)|v2 is a copy of v1| |vector<T> v2 = v1|v2 is a copy of v1| |vector<T> v3(n,val)|v3 has n elements of val| |vector<T> v4(n)|v4 has n copies of a value-initialized object| |vector<T> v5{a,b,c,...}|v5 has many initializers| |vector<T> v5 = {a,b,c,...}|v5 has many initializers| |||

vector<int> v1(10); // v1 has ten elements with value 0 
vector<int> v2{10}; // v2 has one element with value 10
vector<int> v3(10, 1); // v3 has ten elements with value 1 
vector<int> v4{10, 1}; // v4 has two elements with values 10 and 1


This is a new for variant, which can iterate a data structure which supports iterator, like built-in array, vector and string.

for (auto i : v) { } // this can access all the elements in a list, but cannot modify

for (auto& i : v){ } // this can access and modify all the elements in a list

In order to make a data structure iterable, it must work similarly to the existing STL iterators.

  • There must be begin and end methods that operate on that structure, either as members or as stand-alone functions, and that return iterators to the beginning and end of the structure
  • The iterator itself must support an operator* method, an operator != method, and an operator++ method, either as members or as stand-alone functions (you can read more about operator overloading)

Note that operator++ should be the prefix version, which is done by declaring a function called operator++ that takes no arguments.

excerpted from here

begin and end functions

The new STL provides 2 functions to automatically figure out the begin and end of an array. This way, programmers could avoid manually specify the beginning and end position.

int ia[] = {1,2,3,4,5,6,7,8,9,0};
int * beg = begin(ia);
int * end = end(ia);

lvalue and rvalue

Roughly speaking, when we use an object as an rvalue, we use the object’s value (its contents). When we use an object as an lvalue, we use the object’s identity (its location in memory).

Bitwise operations

Operator Function Use
~ bitwise NOT ~expr
<< left shift expr1 << expr2
>> right shift expr1 >> expr2
& bitwise AND expr1 & expr2
^ bitwise XOR expr1 ^ expr2
| bitwise OR expr1 | expr2

Type conversions

  1. static_cast is the most simple conversion.

     void * p = &d;
     double * dp = static_cast<double*>(p);
  2. const_cast is to revoke the constness
  3. reinterpret_cast performs a low-level reinterpretation.
  4. old style cast can perform const_cast, static_cast or reinterpret_cast. When const_cast or static_cast is legal, the old style will perform these two, or it will perform reinterpret_cast.


  1. The new standard requires the quotient to be rounded toward zero.
  2. sizeof an array is the size of the entire array.

     // sizeof(ia)/sizeof(*ia) returns the number of elements in ia
     constexpr size_t sz = sizeof(ia)/sizeof(*ia);
  3. C++ allows anonymous objects, for example:

     throw runtime_error("ERROR");


     func(obj()); // obj is a class identifier

Disclaimer: This is a personal weblog. The opinions expressed here represent my own and not those of any entity with which I have been, am now, or will be affiliated.