slide1
Download
Skip this Video
Download Presentation
C++11

Loading in 2 Seconds...

play fullscreen
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
slide1

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

C++11

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

vector::const_iterator i;

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

code here...

}

range based for loops1
Range based for loops

C++11

vector myvector;

for (int i : myvector ) {

code here...

}

even nicer
Even nicer

C++03

vector> dict;

vector>::const_iterator i;

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

code here...

}

even nicer1
Even nicer

C++11, first round

vector> dict;

for (pair i : dict) {

code here...

}

even nicer2
Even nicer

C++11, second round

vector> 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> 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(z));

};

default initialization
Default initialization

C++11

struct MyStruct {

int field = 42;

std::string str = “Hello there”;

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

};

Here you can see a new concept: initializer list

initializer list
Initializer list

classMyClass {

public:

MyClass(std::initializer_list 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!
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 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 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(),

bind(greater_equal(), _1, lo),

bind(less(), _1, hi)));

applying lambdas in the stl1
Applying lambdas in the STL

Before

std::vector 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 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_ptr{1};

Rather than

std::unique_ptr 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
slide49
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