Presented by Wang Jiajun
Formerly known as C++0x. But they failed to complete the standard before 2010. :(
A new non-const reference type called an rvalue reference, identified by T&&
Why?
How to swap two number?
void swap(int &a, int &b)
{
int temp = a;
a = b;
b = temp;
}
The swap function can be time-consuming when coming to class
void naiveswap(string &a, string &b)
{
string temp = a;
a = b;
b = temp;
}
Memory allocated, object copy...
Why can't we only swap the char* of the objects?
Turns a lvalue into a rvalue
void ProcessValue(int& i) {
std::cout << "LValue processed: " << i << std::endl;
}
void ProcessValue(int&& i) {
std::cout << "RValue processed: " << i << std::endl;
}
int main() {
int a = 0;
ProcessValue(a);
ProcessValue(std::move(a));
}
LValue processed: 0
RValue processed: 0
class Movable
{
Movable (Movable&&); //move constructor
Movable&& operator=(Movable&&); //move assignment operator
};
template <class T> swap(T &a, T &b)
{
T tmp(std::move(a)); // move a to tmp
a = std::move(b); // move b to a
b = std::move(tmp); // move tmp to b
}
A common need
template <typename T> void forward_value(const T &val) {
process_value(val);
}
template <typename T> void forward_value(T &val) {
process_value(val);
}
int a = 0;
const int &b = 1;
forward_value(a); // int&
forward_value(b); // const int&
forward_value(2); // int&
So we must overload lots of functions :(
template <typename T> void forward_value(T &&val) {
process_value(val);
}
int a = 0;
const int &b = 1;
forward_value(a); // int&
forward_value(b); // const int&
forward_value(2); // int&&
Designed to reduce the amount of code the programmer has to write
A new keyword to guarantee that a function or object constructor is a compile-time constant.
What will happen when running the code?
int get_five() {return 5;}
int some_value[get_five() + 7];
Compile error!
Now, we can use constexpr:
constexpr int get_five() {return 5;}
int some_value[get_five() + 7];
A class/struct/union is considered POD if it is trivial, standard-layout, and all of its non-static data members and base classes are PODs.
extern template class std::vector<MyClass>;
Tell the compiler not to instantiate the template in this translation unit.
In C, you can quick initialize a struct like this:
struct Object {
float first;
int second;
};
Object scalar = {0.43f, 10}; //One Object, with first=0.43f and second=10
Object anArray[] = {{13.4f, 3}, {43.28f, 29}, {5.934f, 17}}; //An array of three Objects
What about C++ class (e.g. std::Vector)?
vector<string> v = { "xyzzy", "plugh", "abracadabra" };
This can be very very useful!
Define a new constructor:
class SequenceClass {
public:
SequenceClass(std::initializer_list<int> list);
};
Then...
SequenceClass some_var = {1, 4, 5, 6};
How to initialize a class?
Obj var(foo);
Obj *ptr = new Obj(foo);
But in initializer lists we use curly brace {}, not parenthesis ()
They are not uniform...
struct BasicStruct {
int x;
double y;
};
struct AltStruct {
AltStruct(int x, double y) : x_{x}, y_{y} {}
private:
int x_;
double y_;
};
BasicStruct var1{5, 3.2};
AltStruct var2{2, 4.3};
struct IdString {
std::string name;
int identifier;
};
IdString get_string() {
return {"foo", 42}; //Note the lack of explicit type.
}
If we travelling a std container like vector:
for (std::vector<int>::const_iterator itr = myvec.cbegin(); itr != myvec.cend(); ++itr)
Use auto to shorten the code:
for (auto itr = myvec.cbegin(); itr != myvec.cend(); ++itr)
int some_int;
decltype(some_int) other_integer_variable = 5;
A new syntax for the for loop:
int my_array[5] = {1, 2, 3, 4, 5};
// double the value of each element in my_array:
for (int &x : my_array) {
x *= 2;
}
// similar but also using type inference for array elements
for (auto &x : my_array) {
x *= 2;
}
It looks like:
[capture](parameters)->return-type {body}
int main()
{
char s[]="Hello World!";
int Uppercase = 0; //modified by the lambda
for_each(s, s+sizeof(s), [&Uppercase] (char c) {
if (isupper(c))
Uppercase++;
});
cout<< Uppercase<<" uppercase letters in: "<< s<<endl;
}
What's wrong with this code?
template<class Lhs, class Rhs>
decltype(lhs+rhs) adding_func(const Lhs &lhs, const Rhs &rhs) {return lhs + rhs;}
lhs and rhs have not yet been defined!
template<class Lhs, class Rhs>
auto adding_func(const Lhs &lhs, const Rhs &rhs) -> decltype(lhs+rhs) {return lhs + rhs;}
C++11 allows constructors to call other peer constructors.
This feature has already built in Java and C#.
class SomeType {
int number;
public:
SomeType(int new_number) : number(new_number) {}
SomeType() : SomeType(42) {}
};
In C++03, it is possible to accidentally create a new virtual function, when one intended to override a base class function. For example:
struct Base {
virtual void some_func(float);
};
struct Derived : Base {
virtual void some_func(int);
};
C++11 provides syntax to solve this problem.
struct Base {
virtual void some_func(float);
};
struct Derived : Base {
// error!
virtual void some_func(int) override;
};
Prevent inheriting from classes
struct Base1 final { };
struct Derived1 : Base1 { }; // Error!
Preventing overriding methods in derived classes
struct Base2 {
virtual void f() final;
};
struct Derived2 : Base2 {
void f(); // Error!
};
In C++03, we use NULL to represent null pointer.
But if NULL is defined as 0 (which is usually the case in C++), what will happen in the following code?
void foo(char *);
void foo(int);
foo(NULL);
In C++11, you should write:
foo(nullptr);
The type-safe enumeration
enum class Enumeration {
Val1,
Val2,
Val3 = 100,
Val4 // = 101
};
Enumeration::Val4 == 101 // error!
C++03's parser defines ">>" as the right shift operator in all cases
vector<vector<int>> arr1; // Compile error!
vector<vector<int> > arr2;
The explicit keyword can now be applied to conversion operators
explicit operator bool();
In C++03, you can use typedef to make a alias. But not for template!
template <typename First, typename Second, int Third>
class SomeType;
template <typename Second>
typedef SomeType<OtherType, Second, 5> TypedefName; // Illegal in C++03
C++11 adds this ability with the following syntax:
template <typename Second>
using TypedefName = SomeType<OtherType, Second, 5>;
Now, everything except reference can live in a union.
template<typename... Values> class tuple;
tuple<int, std::vector<int>, std::map<std::string, std::vector<int>>> some_instance_name;
Three Unicode encodings that C++11 supports: UTF-8, UTF-16, and UTF-32
C++11 adds two new character types: char16_t and char32_t
u8"I'm a UTF-8 string."
u"This is a UTF-16 string."
U"This is a UTF-32 string."
C++11 provides a raw string literal:
R"(The String Data \ Stuff " )"
R"delimiter(The String Data \ Stuff " )delimiter"
OutputType operator "" _suffix(const char * literal_string);
OutputType some_variable = 1234_suffix;
The C++11 standardizes support for multithreaded programming.
Define a tls: thread_local
default:
struct SomeType {
SomeType() = default; //The default constructor is explicitly stated.
SomeType(OtherType value);
};
delete:
struct NonCopyable {
NonCopyable() = default;
NonCopyable(const NonCopyable&) = delete;
NonCopyable & operator=(const NonCopyable&) = delete;
};
struct NoInt {
void f(double i);
void f(int) = delete;
};
......
template<class T>
struct Check {
static_assert(sizeof(int) <= sizeof(T), "T is not big enough!");
};
struct SomeType { OtherType member; };
sizeof(SomeType::member); // Does not work with C++03. Okay with C++11
Many new improvements!
Still lack something useful: XML, GUI, socket, reflection...
C++ is still evolving!
C++14, C++17...
Master in C++? Maybe no one and never...