C++11
Download
1 / 50

C++11 - PowerPoint PPT Presentation


  • 118 Views
  • Uploaded on

C++11. Alejandro Álvarez & Andrea Valassi. White Area Lectures - April 19th, 2014. Overview. Previous standard was C++03 Bug-fixes over C++98 C++11 released on August 2011 C++14 already on its way bringing small improvements Previously known as C++0x You can expect

loader
I am the owner, or an agent authorized to act on behalf of the owner, of the copyrighted work described.
capcha
Download Presentation

PowerPoint Slideshow about ' C++11' - kesler


An Image/Link below is provided (as is) to download presentation

Download Policy: Content on the Website is provided to you AS IS for your information and personal use and may not be sold / licensed / shared on other websites without getting consent from its author.While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server.


- - - - - - - - - - - - - - - - - - - - - - - - - - E N D - - - - - - - - - - - - - - - - - - - - - - - - - -
Presentation Transcript

C++11

Alejandro Álvarez & Andrea Valassi

White Area Lectures - April 19th, 2014


Overview
Overview

  • Previous standard was C++03

    • Bug-fixes over C++98

  • C++11 released on August 2011

    • C++14 already on its way bringing small improvements

    • Previously known as C++0x

  • You can expect

    • A few small improvements that will make your code (even) nicer

    • A more powerful standard library that will make your life easier


Those little things

Those “little” things

Easier to write and to read


The space after the
The space after the >

C++03

vector<complex<double> > a;

C++11

vector<complex<double>> a;


Nullptr
nullptr

C++03

MyClass *ptr = NULL;

C++11

MyClass *ptr = nullptr;

nullptr is a pointer and only a pointer, so you can’t do

int a = nullptr;


Range based for loops
Range based for loops

C++03

vector<int> myvector;

vector<int>::const_iterator i;

for (i = myvector.begin(); i != myvector.end(); ++i) {

code here...

}


Range based for loops1
Range based for loops

C++11

vector<int> myvector;

for (int i : myvector ) {

code here...

}


Even nicer
Even nicer

C++03

vector<pair<string,double>> dict;

vector<pair<string,double>>::const_iterator i;

for (i = dict.begin(); i != dict.end(); ++i) {

code here...

}


Even nicer1
Even nicer

C++11, first round

vector<pair<string,double>> dict;

for (pair<string,double> i : dict) {

code here...

}


Even nicer2
Even nicer

C++11, second round

vector<pair<string,double>> dict;

for (auto i : dict) {

code here...

}

The auto keyword can be used to let the compiler infer the type.

Can not be used for function parameters.


Another example of auto
Another example of auto

C++03

std::vector<std::pair<std::string, ns::MyType>> x = my_function();

C++11

auto x = my_function();


Constructors can be inherited
Constructors can be inherited!

classBase {

public:

Base(int x);

Base(int x, int y);

Base(double z);

};


Constructors can be inherited1
Constructors can be inherited!

C++03

classDerived: publicBase {

public:

Derived(int x): Base(x);

Derived(int x, int y): Base(x, y);

Derived(double z): Base(z);

};


Constructors can be inherited2
Constructors can be inherited!

C++11

classDerived: publicBase {

public:

usingBase::Base;

};


Constructor delegation
Constructor delegation

C++11

classBase {

public:

Base();

Base(int x): Base(x, 0);

Base(int x, int y): Base();

Base(double z): Base(static_cast<int>(z));

};


Default initialization
Default initialization

C++11

struct MyStruct {

int field = 42;

std::string str = “Hello there”;

std::vector<int> v = {1, 2, 3, 4};

};

Here you can see a new concept: initializer list


Initializer list
Initializer list

classMyClass {

public:

MyClass(std::initializer_list<int> v);

}

So you can do now

MyClass a = {1, 2, 4, 20};


Default and delete
Default and delete

classMyClass {

public:

MyClass() =default;

MyClass(constMyClass& b) = delete;

}

defaultPredefined constructor

deleteForbid usage


Final and override
Final and override

structDerived : publicBase {

virtualvoiddoit(int, int, int) constoverridefinal;

};

structReDerived : publicDerived {

virtualvoiddoit(int, int, int) constoverride;

};

That’s a compilation time error

Note that this is an optional feature


Those little things1
Those “little” things

  • You have seen they make your code

    • Easier to write

    • Easier to read

    • Less boilerplate

    • Less repetitive

  • So use them!


The powerful features

The powerful features

More for less


Lambdas
Lambdas!

auto greater = [](int a, int b) { return a > b; };

greater(22, 33); // returns false

The compiler figures out the return type (really!), but you can be explicit

auto greater = [](int a, int b) -> bool { return a > b; };


Lambdas closures
Lambdas! (Closures)

"A closure is essentially a stateful function that carries around with it a value or a reference to a variable defined outside the body of the function”

You will see it clearer with the following example


Lambdas closures1
Lambdas! (Closures)

size_t val;

auto callback = [&val] (size_t a) { val = a; };

func_with_callback(“hello”, callback);

You can also capture by value [=val]

You can capture everything[=] [&]

You can capture this[this]

Remember that the object life is not extended!!!!!


How do i receive a lambda
How do I receive a lambda?

A lambda is a function, so, how do you receive a function?

voidmy_func(std::function<int(double, double)> f);

That means: f is a callable that receives two doubles and return an integer.

Let it be a lambda, a functor, a function, ….


Applying lambdas in the stl
Applying lambdas in the STL

Before

std::vector<int> c{1,9,2,8,3,7,4,6,5};

int lo = 4;int hi = 7;

usingstd::bind; usingstd::logical_and;

usingstd::less; usingstd::greater_equal;

usingnamespacestd::placeholders;

auto i = find_if(begin(c), end(c),

bind(logical_and<bool>(),

bind(greater_equal<int>(), _1, lo),

bind(less<int>(), _1, hi)));


Applying lambdas in the stl1
Applying lambdas in the STL

Before

std::vector<int> c{1,9,2,8,3,7,4,6,5};

int lo = 4;int hi = 7;

auto i2 = find_if(begin(c), end(c),

[=](int i) { return i >= lo && i < hi;}

);


Move semantics
Move semantics

  • This is one of the biggest improvements in C++11

  • It is also one of the hardest to explain, let’s try with some code


Move semantics1
Move semantics

classVector {

size_t size;

T* array;

};


Move semantics2
Move semantics

void swap(Vector& a, Vector& b){

Vector tmp = a;

a = b;

b = tmp;

};

This operation is a waste of cycles

tmp->array allocated and copied from a

a->array freed, re-allocated, copied from b

b->array freed, re-allocated, copied from tmp

tmp->array freed


Move semantics3
Move semantics

  • We could just move the pointer, but that won’t work in multiple cases

    • a = b

    • Do things with a AND b

  • However, it does in many others

    • a = b

    • Do things with a, forget of b

    • swap(a, b)

    • Other situations where the compiler can figure out

    • a = function(); where function returns b, and b falls out of scope


Move semantics4
Move semantics

  • So, basically we have

    • Copies

    • Movements

  • But in C++98

    • Only copy constructor and assignment operator exist

  • Now in C++11

    • Copy constructor

    • Move constructor

    • Copy assignment operator

    • Move assignment operator


Move semantics5
Move semantics

classVector {

size_t size;

T* array;

// Copy constructor

Vector(constVector& o);

// Move constructor

Vector(Vector&& o);

// Copy assignment operator

Vector& operator = (constVector &);

// Move assignment operator

Vector& operator = (Vector &&);

};


Move semantics6
Move semantics

Vector::Vector(constVector& o) {

this->array = newT[o.size];

memcpy(this->array, o.array, o.size * sizeof(T));

}

Vector::Vector(Vector&& o) {

this->array = o.array;

this->size = o.size;

o.array = nullptr;

o.size = 0;

}


Move semantics7
Move semantics

After a move, the “moved” object is unusable (but destructible) until you re-assign something else

void swap(Vector& a, Vector& b){

Vector tmp = std::move(a);

a = std::move(b);

b = std::move(tmp);

};

Now, not a single allocation or freeing!


Move semantics8
Move semantics

  • There is more trickery involved

    • Copy and swap semantics

    • Default move methods provided by compiler if members define move semantics (!)

    • Perfect forwarding

    • lvalues, prvalues, xvalues, gvalues, rvalues (arght!)


Move semantics9
Move semantics

But at least returning by value

BigClass generateBigClass();

BigClass x = generateBigClass();

It is not expensive anymore (and no pointers flying around needed!)


Emplacements
Emplacements

// Assume Big(int) constructor

std::vector<Big> v;

Big b(1);

v.push_back(b); // Copy

v.push_back(std::move(b)); // Move

v.push_back(Big(2)); // Construct, Move

v.push_back({3}); // Construct, Move

v.emplace_back(4); // Construct in place

Basically, it allows to construct in place elements that belong to a container


Talking about pointers
Talking about pointers

  • Smart pointers are in std::!

  • std::unique_ptr

    • Only one owner of the object, can not be copied, can be moved

  • std::shared_ptr

    • Several owners, can be copied, can be moved, when all are destroyed, the object is freed

  • std::weak_ptr

    • Observer of shared_ptr, does not own, but it is notified on release

  • std::auto_ptr

    • Deprecated!


Talking about pointers1
Talking about pointers

new and delete are to be avoid now!

Smart pointers to handle lifetime, or classes that need to (i.e. vector)

std::unique_ptr<Big> big_ptr{1};

Rather than

std::unique_ptr<Big> big_ptr(new Big(1));


Few recommendations
Few recommendations

  • Pass objects by value, reference or pointer

    • unless there is a change in ownership

  • Accept smart pointers by non-const only if it is going to be modified

  • Avoid copying shared_ptr (expensive!)

    • unique_ptr is a better choice, normally

  • Do NOT own bare pointers

  • Accepting unique_ptr by value means I will take ownership

  • Accepting shared_ptr by value means I will share ownership


Summary
Summary

  • C++11 makes coding easier and nicer

  • More efficient without the risk of free range pointers

    • Move semantics

  • And safer

    • Smart pointers


But wait there is more
But wait, there is more!

  • Variadic templates

  • Concurrency

    • std::thread

    • std::async

    • std::promise

    • std::packaged_task

  • New algorithms

  • Hash tables

  • Tuples

  • Type traits

  • constexpr

  • New string literals

    • u8“UTF-8 String”



Compiler support
Compiler support

  • gcc 4.8 has a complete support

  • gcc 4.1 in SL5 does not support it

  • gcc 4.4 in SL6 only partial support

    • No lambdas :(

  • clang 3.4 in SL6 supports it

    • No clang in SL5

    • But…


Compatibility
Compatibility

  • If you are standalone, you are good

    • If you maintain a C++ library, forget about it

    • If you use a C++ library, forget about it

  • Linking clang and gcc binaries likely to break

  • Theoretically, the ABI between C++03 and C++11 are compatible

    • As long as you don’t use the STL!

      • Which is like saying: no, they are not

    • So you need to compile the whole stack in C++03 or C++11, no mixing


Current status

Current status

Of our software stacks


Dmlite
DMLite

  • Is a C++ library used by C++ applications

  • Can only switch on -std=c++11/c++0x when we do so for the whole dependency chain

    • EPEL7?

  • Shame, because there are a couple of ugly constructs that would be way easier with C++11

    • See variadic templates


FTS3

  • Already compiling with -std=c++0x

  • Was written using C++98, so C++11 occurrences are rare (new code)

  • auto keyword is a bless!



ad