New features in C++11

Presented by Wang Jiajun

C++ Standards

  • 1st: C++98
  • 2nd: C++03
  • 3rd: C++11

C++11

Formerly known as C++0x. But they failed to complete the standard before 2010. :(

Core Language

Rvalue references and move constructors

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;
}
						

What about swap two string?

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?

std::move

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
						

The new swap


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
}
						

Perfect Forwarding

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 :(

Perfect Forwarding


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

Constant Expressions: constexpr

A new keyword to guarantee that a function or object constructor is a compile-time constant.

Example

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];
						

Modification to the definition of plain old data (POD)

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 declaration


extern template class std::vector<MyClass>;
					

Tell the compiler not to instantiate the template in this translation unit.

Initializer lists

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)?

Example:


vector<string> v = { "xyzzy", "plugh", "abracadabra" };
						

This can be very very useful!

How to?

Define a new constructor:


class SequenceClass {
public:
    SequenceClass(std::initializer_list<int> list);
};
						

Then...


SequenceClass some_var = {1, 4, 5, 6};
						

Uniform initialization

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...

Introduce the curly brace


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};
						

Even some amazing format


struct IdString {
    std::string name;
    int identifier;
};

IdString get_string() {
    return {"foo", 42}; //Note the lack of explicit type.
}
						

Type inference

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)
						

Determine the type of an expression


int some_int;
decltype(some_int) other_integer_variable = 5;
						

Range-based for loop

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;
}
					

Lambda functions

It looks like:


[capture](parameters)->return-type {body}
						

Example:


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;
}
						

Alternative function syntax

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!

Workaround


template<class Lhs, class Rhs>
auto adding_func(const Lhs &lhs, const Rhs &rhs) -> decltype(lhs+rhs) {return lhs + rhs;}
						

Delegation

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) {}
};
					

Explicit overrides

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;
};
						

Final

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!
};
						

Null pointer constant

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);
					

Strongly typed enumerations

The type-safe enumeration


enum class Enumeration {
    Val1,
    Val2,
    Val3 = 100,
    Val4 // = 101
};

Enumeration::Val4 == 101 // error!
					

Right angle bracket

C++03's parser defines ">>" as the right shift operator in all cases


vector<vector<int>> arr1; // Compile error!
vector<vector<int> > arr2;
					

Explicit conversion operators

The explicit keyword can now be applied to conversion operators


explicit operator bool();
					

Alias templates

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>;
					

Unrestricted unions

Now, everything except reference can live in a union.

Variadic templates


template<typename... Values> class tuple;
tuple<int, std::vector<int>, std::map<std::string, std::vector<int>>> some_instance_name;
					

New string literals

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"
					

User-defined literals


OutputType operator "" _suffix(const char * literal_string);
OutputType some_variable = 1234_suffix;
					

Multithreading memory model

The C++11 standardizes support for multithreaded programming.

Thread-local storage

Define a tls: thread_local

Explicitly defaulted and deleted special member functions

default:


struct SomeType {
    SomeType() = default; //The default constructor is explicitly stated.
    SomeType(OtherType value);
};
						

Explicitly defaulted and deleted special member functions

delete:


struct NonCopyable {
    NonCopyable() = default;
    NonCopyable(const NonCopyable&) = delete;
    NonCopyable & operator=(const NonCopyable&) = delete;
};
						

struct NoInt {
    void f(double i);
    void f(int) = delete;
};
						

Type long long int

......

Static assertions


template<class T>
struct Check  {
    static_assert(sizeof(int) <= sizeof(T), "T is not big enough!");
};
					

sizeof on the members of classes


struct SomeType { OtherType member; };

sizeof(SomeType::member); // Does not work with C++03. Okay with C++11
					

Others

  • Control and query object alignment
  • Allow garbage collected implementations

Standard Library

  • Upgrades to standard library components
  • Threading facilities
  • Tuple types
  • Hash tables
  • Regular expressions
  • General-purpose smart pointers
  • Extensible random number facility
  • ...

Conclusion

Many new improvements!

Still lack something useful: XML, GUI, socket, reflection...

Future

C++ is still evolving!

C++14, C++17...

Master in C++? Maybe no one and never...

Thanks