This article summarizes the new features of C++ 11. This list is summarized according to Bo Qian’s youtube channel: https://www.youtube.com/playlist?list=PL5jc9xFGsL8FWtnZBeTqZBbniyw0uHyaH
If you are new to C++, I personally highly recommend following his channel. His tutorial is well organized and easy to follow. If you just want to quickly go through the list, just scroll down. Let’s start.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include<iostream> | |
#include<vector> | |
#include<string> | |
#include<iterator> | |
using namespace std; | |
/******************************************************************************************************/ | |
/* 1. Initializer list */ | |
//Implemented by initilaizer list constructor | |
vector<int> v = {1, 4, 6, 10}; | |
//All the relevant STL containers have been updated to accept the initializer list (e.g. map, list) | |
//Customized the initializer constructor for our own classes | |
//For example: | |
#include<initializer_list> | |
class OurStudents{ | |
private: | |
vector<int> m_studentID; | |
public: | |
OurStudents(const initializer_list<int> & studentLists){ | |
for(initializer_list<int>::iterator it = studentLists.begin(); it != studentLists.end(); ++it){ | |
m_student.push_back(*it); | |
} | |
} | |
}; | |
OurStudents OurStudents_T1 = {12, 3, 4}; | |
OurStudents OurStudents_T2{12, 3, 4}; //The same as above | |
/******************************************************************************************************/ | |
/* 2. Uniform Initialization */ | |
//C++ 03 | |
class dog{ //Aggregate class or struct | |
public: | |
int age; | |
string name; | |
}; | |
dog d1 = {2, "Jack"}; // Aggregate initialization | |
//C++ 11 extended the scope of curly brace initialization | |
class dog{ | |
public: | |
dog(int age, string name){ | |
//… | |
} | |
}; | |
dog d2 = {2, "Jack"}; //As long as we have a matching constructor in our class, this is valid | |
//All three initialization takes exact the same form, however, from compiler's perspective, they are | |
//different | |
/* | |
The priority of three forms: | |
1. Initializer list constructor (first priority) | |
2. Regular constructor takes appropriate parameters | |
3. Aggregate initializer | |
*/ | |
/******************************************************************************************************/ | |
/* 3. auto type */ | |
vector<int> myVec = {3, 4, 4}; | |
vector<int>::iterator it = myVec.begin(); | |
//===the same as above | |
auto it = myVec.begin(); | |
/******************************************************************************************************/ | |
/* 4. foreach */ | |
for(int i : myVec){ // Work only with classes which have begin() and end() methods | |
cout<<i; // read-only | |
} | |
for(int &i : myVec){ | |
i++; // | |
} | |
/******************************************************************************************************/ | |
/* 5. nullptr */ | |
//Replace NULL in C++03 | |
//Compared with NULL, nullptr always represents a pointer. | |
void foo(int i){cout << "foo int" << endl;} | |
void foo(char *i){cout << "foo pointer" << endl;} | |
int main(){ | |
foo(NULL); //Ambiguity | |
foo(nullptr)// always call foo(char *i) | |
return 0; | |
} | |
/******************************************************************************************************/ | |
/* 6. enum class */ | |
//C++ 11 | |
enum class apple{green, red}; | |
enum class orange(big, small); | |
apple A = apple::green; | |
orange O = orange::big; | |
if(A == O){//Compile error, you should define ==(apple, orange) first | |
//… | |
} | |
/******************************************************************************************************/ | |
/* 7. static_assert */ | |
//runtime assert | |
assert(ptr != nullptr); | |
//Compile time assert | |
static_assert(sizeof(int) == 4); | |
/******************************************************************************************************/ | |
/* 8. Delegating Constructor */ | |
//Won't work in C++, work in Java | |
class dog{ | |
public: | |
dog(){ … } | |
dog(int a){ | |
dog(); | |
//Other staff here; | |
} | |
} | |
//C++ 03 | |
class dog{ | |
public: | |
void init(){ … }; //Add one more function here which will be used in both constructors | |
dog(){ init(); } | |
dog(int a){ | |
init(); | |
//Other staff here; | |
} | |
} | |
/*Downsides: | |
1. Cubersome code | |
2. init() maybe invoked by other | |
*/ | |
//C++ 11, limitation: first constructor dog() is always called first | |
class dog{ | |
int m_age = 9; // C++ 11 initialize member variable directly | |
public: | |
dog(){ … } | |
dog(int a) : dog() { | |
//Other staff here; | |
} | |
} | |
/******************************************************************************************************/ | |
/* 9. Override for virtual functions */ | |
//To avoid inadvertently create new functions in derived class | |
class dog{ | |
virtual void A(int a); | |
virtual void B() const; | |
}; | |
class YellowDog : dog{ | |
/* Explicitly tell the compiler that A and B should override the function from parent class. | |
In this case, since we cannot find any valid function to override. Compiler will issue errors. | |
*/ | |
virtual void A(float) override; //error | |
virtual void B() override;//error | |
} | |
/******************************************************************************************************/ | |
/* 10. final key word for virtual function and class */ | |
class dog final { //No class can be derived from dog any more | |
//… | |
}; | |
class dog { | |
virtual void bark() final; //No derived class can override bark() any more | |
}; | |
/******************************************************************************************************/ | |
/* 11. Compiler generated default constructor */ | |
/* | |
Typically, compiler will not generate default constructor if we provide one. However, in C++ 11 we can | |
force the compiler to generate default constructor. | |
*/ | |
class dog{ | |
public: | |
dog(int age){ | |
//… | |
} | |
}; | |
dog D1; //error: compiler cannot find constructor with no parameters | |
class dog{ | |
public: | |
dog(int age){ | |
//… | |
} | |
dog() = default; //Force the compiler to generate a default constructor | |
}; | |
dog D1; // OK | |
/******************************************************************************************************/ | |
/* 12. delete key word */ | |
class dog{ | |
dog(int age){ | |
//… | |
} | |
}; | |
dog D1(3); //OKay, with constructor we provide | |
dog D2(4.0); //Okay, compiler will convert double to int and call the constructor we provide | |
D1 = D2; //Okay, compiler will generate an assign constructor override for us | |
/* | |
If we want to restrict such situations, let's say users can only give integer as the age, we can restrict | |
compiler by delete key word | |
*/ | |
class dog{ | |
dog(int age){ | |
//… | |
} | |
dog(double age) = delete; | |
dog& operator=(const dog& d) = delete; | |
}; | |
dog D1(3); //OKay, with constructor we provide | |
dog D2(4.0); //Compile error | |
D1 = D2;//Compile error | |
/******************************************************************************************************/ | |
/* 13. constexpr */ | |
int A[6]; // It's OKay | |
int Func(){return 3;} | |
int A[Func() + 3];//Error: Compile does not know the return value at compile time | |
//Force the computation to happen at compile time, the return value is treated as constant value | |
constexpr int Func(){return 3;} | |
int A[Func()+ 3];//Okay, an array with length to be 6 | |
//Write a faster program | |
constexpr int cubed(int x){ return x*x*x; } //Compile time calculation | |
int k = cubed(26); | |
/******************************************************************************************************/ | |
/* 14. New string literals */ | |
//C++ 03 | |
char *a = "Hello World"; | |
//C++ 11 | |
char *a = u8"Hello World"; //UTF 8 string | |
char16_t *b = u"Hello World"; //UTF 16 string | |
char32_t *c = U"Hello World"; //UTF 32 string | |
char* d = R"(Hello World)"; //Raw string | |
/******************************************************************************************************/ | |
/* 15. lambda function */ | |
cout << [](int x, int y){return x + y;}(3, 4) << endl; //print 7 | |
auto f = [](int x, int y){return x + y;}; | |
cout << f(3, 4) << endl; //print 7 | |
template<typename func> | |
void filter(func f, vector<int>& A){ | |
for(auto i : A){ | |
if(f(i)) | |
cout << i << " "; | |
} | |
} | |
int main(){ | |
vector<int> V = {1,2,3,4,5,6}; | |
int y = 4; | |
filter([](int x){return x>3;}, V); // Print out 4 5 6 | |
filter([&](int x){return x > y;}, V); // Print out 5 6 | |
//Note: [&] tells the compiler that we want variable capture | |
return 0; | |
} |
Thanks for reading.