Top Banner
May 30,2011 Advanced C++
62
Welcome message from author
This document is posted to help you gain knowledge. Please leave a comment to let me know what you think about it! Share it to your friends and learn new things together.
Transcript
Page 1: Advanced c++ ver 1.1

May 30,2011

Advanced C++

Page 2: Advanced c++ ver 1.1

“The contents here are for Aricent Group internal training purposes only and do not carry any commercial value” 2Restricted ©Aricent Group 2011

• Introduction to STL

•Type traits

•SFINAE and RAII

•C++11 features

Agenda

Page 3: Advanced c++ ver 1.1

“The contents here are for Aricent Group internal training purposes only and do not carry any commercial value” 3Restricted ©Aricent Group 2011

STL (Standard Template Library) contains three foundational items

• Containers

– Objects that hold objects

– Sequence containers (list, deque, vector ..): basically a linear list

– Associative containers (map): efficient retrieval of value base on key

• Algorithms

– Act on containers

– Provide means to manipulate the content of containers (initialization, sorting, searching and transforming)

– Many algorithms operates on a range of elements within a container

• Iterators

– More or less a pointer which used to access elements of containers

– Give the capability to cycle through the content of containers

Introduction to STL

Page 4: Advanced c++ ver 1.1

“The contents here are for Aricent Group internal training purposes only and do not carry any commercial value” 4Restricted ©Aricent Group 2011

The STL also relies upon several standard components for support

• Allocators

– Manage memory allocation for a container

– Users can define their own allocator but for most uses, the default ones is sufficient

• Predicates

– Several of algorithms and containers use a special type of function call predicates which returns True or False based on precise conditions defined by users

– A unary predicate takes one argument while a binary predicate has two

– In binary predicates, the arguments are always in the order of first, second

– Some algorithms and classes use a special types of binary predicates which return if 1st argument is less than 2nd one. They are known as comparison functions.

• Function objects

– Objects that define the operator( )

Introduction to STL

Page 5: Advanced c++ ver 1.1

“The contents here are for Aricent Group internal training purposes only and do not carry any commercial value” 5Restricted ©Aricent Group 2011

Container Classes

Page 6: Advanced c++ ver 1.1

“The contents here are for Aricent Group internal training purposes only and do not carry any commercial value” 6Restricted ©Aricent Group 2011

Vectors are sequence containers representing arrays that can change in size.

• Sequential

– Elements are ordered in a strict linear sequence

– Individual elements are accessed by their position in the sequence

• Dynamic Array

– Allow direct access to any element in the sequence

– Support pointer arithmetic (array-like style through operator [ ])

• Allocator aware

– Use an allocator object to dynamically handle its need of storage

Container Classes - Vector

Page 7: Advanced c++ ver 1.1

“The contents here are for Aricent Group internal training purposes only and do not carry any commercial value” 7Restricted ©Aricent Group 2011

Simple examples of using vector

• Demonstrate a vector (accessing by using array-like style and iterator)

– Refer to example vector1.cpp

• Insert and delete elements of a vector

– Refer to example vector2.cpp

• Store class object in a vector

– Refer to example vector3.cpp

Container Classes - Vector

Page 8: Advanced c++ ver 1.1

“The contents here are for Aricent Group internal training purposes only and do not carry any commercial value” 8Restricted ©Aricent Group 2011

Lists are sequence containers that allow constant time insert and erase operations anywhere within the sequence, and iteration in both directions

• Sequential

– Elements are ordered in a strict linear sequence

– Individual elements are accessed by their position in the sequence

• Double-linked list

– Each element keeps information on how to locate the next and previous element

– No direct random access

• Allocator aware

– Use an allocator object to dynamically handle its need of storage

Container Classes - List

Page 9: Advanced c++ ver 1.1

“The contents here are for Aricent Group internal training purposes only and do not carry any commercial value” 9Restricted ©Aricent Group 2011

Simple examples of using list

• Demonstrate a list

– Prefer to example list1.cpp

• Sort and merge lists

– Prefer to example list2.cpp

• Store class object in a list

– Prefer to example list3.cpp

Container Classes - List

Page 10: Advanced c++ ver 1.1

“The contents here are for Aricent Group internal training purposes only and do not carry any commercial value” 10Restricted ©Aricent Group 2011

Which one is the most appropriate ?

• If search is the most frequent operation

• If insertion at the end is the most frequent operation

• If insertion at the middle is the most frequent operation

Container Classes – Vector versus List

Page 11: Advanced c++ ver 1.1

“The contents here are for Aricent Group internal training purposes only and do not carry any commercial value” 11Restricted ©Aricent Group 2011

Map are associative containers that store elements formed by a combination of key value and mapped value, following a specific order

• Associative

– Element are referenced by their key, not by their absolute position in the container

• Ordered

– Elements follow a strict order at all time

• Map

– Each element associate a key to a mapped value: keys are meant to identify the element whose main content is the mapped value

• Unique key

– No two elements in the container can have equivalent key

• Allocator-aware

– Use allocator objects to dynamically handle its storage needs

Container Classes - Map

Page 12: Advanced c++ ver 1.1

“The contents here are for Aricent Group internal training purposes only and do not carry any commercial value” 12Restricted ©Aricent Group 2011

Simple examples of using map

• Simple map demonstration

– Refer to example map1.cpp

• Store object class in a map

– Refer to example map2.cpp

Container Classes - Map

Page 13: Advanced c++ ver 1.1

“The contents here are for Aricent Group internal training purposes only and do not carry any commercial value” 13Restricted ©Aricent Group 2011

Container adaptor refers to an adaption of normal containers my modifying and restricting its interface for some special purposes

• Stack

– Adapts the deque container to provide strict LIFO behavior

• Queue

– Adapts the deque container to provide strict FIFO behavior

• Priority_queue

– Adapt the vector container to maintain item in a sorted order

Container Adaptor

Page 14: Advanced c++ ver 1.1

“The contents here are for Aricent Group internal training purposes only and do not carry any commercial value” 14Restricted ©Aricent Group 2011

• Rich set of templates functions

• Can work with any kind of container

• Provide extended operation besides basic operation supported by the containers

• Detailed information can be found at http://www.cplusplus.com/reference/algorithm/

Algorithm

Page 15: Advanced c++ ver 1.1

“The contents here are for Aricent Group internal training purposes only and do not carry any commercial value” 15Restricted ©Aricent Group 2011

• Example of using count_if

- count_if returns the number of elements in the sequence that satisfy some predicated

- Refer to example count_if.cpp

• Example of using transforming a sequence

– Transform modifies each element in a range according a function you provide

– Refer to example transform1.cpp (using predicate)

– Refer to example transform2.cpp (using function object)

Algorithm

Page 16: Advanced c++ ver 1.1

“The contents here are for Aricent Group internal training purposes only and do not carry any commercial value” 16Restricted ©Aricent Group 2011

Function objects are an object with an overloaded operator ( ) (function call operator)

• Function objects is use widely in STL

– In Container

template < class Key,

class Traits=less<Key>,

class Allocator=allocator<Key> > class set

– In Alogrithm

template<class Iterator, class Function>

Function for_each(Iterator first, Iterator last, Function f) {

while (first != end) { f(*first); ++first; }

return f;

}

Function Objects

Page 17: Advanced c++ ver 1.1

“The contents here are for Aricent Group internal training purposes only and do not carry any commercial value” 17Restricted ©Aricent Group 2011

• Function object can keep the state of the context they are called

• Example: you need to write a program which help the user sort the inbox on different field – to, form, date, etc …

– What will happen if you use function pointer ?

• You probably need to write a new routine that knows about your field type because the STL sort routine does not know about your field type

– Is there an elegant way to write the program using function object and STL sort routine ?

Function Object

Page 18: Advanced c++ ver 1.1

“The contents here are for Aricent Group internal training purposes only and do not carry any commercial value” 18Restricted ©Aricent Group 2011

Example:

class Message {

public:std::string getHeader (const std::string& header_name) const;

// other methods…

};

class MessageSorter {

public: MessageSorter (const std::string& field) : _field( field ) {}

bool operator (const Message& lhs, const Message& rhs){

// get the field to sort by and make the comparison

return lhs.getHeader( _field ) < rhs.getHeader( _field );

}

private:

std::string _field;

};

Function Object

Page 19: Advanced c++ ver 1.1

“The contents here are for Aricent Group internal training purposes only and do not carry any commercial value” 19Restricted ©Aricent Group 2011

Example:

std::vector<Messages> messages;

// read in messages

MessageSorter comparator(“to”);

sort( messages.begin(), messages.end(), comparator );

Function Object

Page 20: Advanced c++ ver 1.1

“The contents here are for Aricent Group internal training purposes only and do not carry any commercial value” 20Restricted ©Aricent Group 2011

– Random Access

• Can access elements at an arbitrary offset position relative to element they point to

• Support operation ( a += n; a -= n; a + n; a – n; …)

– Bidirectional

• Can access elements in both directions (toward to end() and toward to beginning())

• Does not support ( a += n; a -= n; a + n; a – n; …)

– Forward

• Can access elements in on direction (toward end())

– Input

• Can be used in sequential input operations where each pointed value is read only once and the iterator is increased

– Output

• Can be used in sequential output operations where each pointed value is read only once and the iterator is increased

Iterator

Page 21: Advanced c++ ver 1.1

“The contents here are for Aricent Group internal training purposes only and do not carry any commercial value” 21Restricted ©Aricent Group 2011

– Reverse iterator

• Either a random access iterator or a bidirectional iterator

• Increasing the iterator will result to a “pointer” to the previous element

– Const iterator

• Point to a type of “const T”

Iterator

Page 22: Advanced c++ ver 1.1

“The contents here are for Aricent Group internal training purposes only and do not carry any commercial value” 22Restricted ©Aricent Group 2011

Allocators handle all the request for allocation and deallocation of memory for a given container

• Example

– template <class T, class Allocator = allocator<T>> class vector

• You can think of allocator as a “black box”.

– You may select a containers’ memory allocation strategy by instantiating the container with a particular allocator but should not make any assumptions about how the container actually uses the allocator

– Default allocator is quite sufficient for most of the cases while custom allocator is used to improve performance on particular systems

Allocator

Page 23: Advanced c++ ver 1.1

“The contents here are for Aricent Group internal training purposes only and do not carry any commercial value” 23Restricted ©Aricent Group 2011

Available type of allocators

• Alloc

– Default allocator

– Thread safe, usually has the best performance characteristic

• Pthread_alloc

– Thread safe, use different memory pool for each thread

– Usually faster than alloc, especially on multiprocessor systems

– Cause resouce fragmentation

• Single_client_alloc

– Fast but thread-unsafe allocator, can be faster then alloc if the program has only one thread

• Malloc_alloc

– Use standard function malloc

– Slow

Allocator

Page 24: Advanced c++ ver 1.1

“The contents here are for Aricent Group internal training purposes only and do not carry any commercial value” 24Restricted ©Aricent Group 2011

Memory pool allocator

Page 25: Advanced c++ ver 1.1

“The contents here are for Aricent Group internal training purposes only and do not carry any commercial value” 25Restricted ©Aricent Group 2011

Shared memory allocator

Page 26: Advanced c++ ver 1.1

“The contents here are for Aricent Group internal training purposes only and do not carry any commercial value” 26Restricted ©Aricent Group 2011

Garbage collector allocator

Page 27: Advanced c++ ver 1.1

“The contents here are for Aricent Group internal training purposes only and do not carry any commercial value” 27Restricted ©Aricent Group 2011

What is traits ?

- Think of a trait as a small object whose main purpose is to carry information used by another object or algorithm to determine "policy" or "implementation details". - Bjarne Stroustrup

Why we need traits ?

- Traits are important because they allow you to make compile-time decisions based on types

- Adding the proverbial "extra level of indirection" that solves many software engineering problems

Type traits

Page 28: Advanced c++ ver 1.1

Type traits

//return the largest value of an array

template< class T >

T findMax(const T const * data,

const size_t const numItems) {

// Obtain the minimum value for type T

T largest = std::numeric_limits< T >::min();

for(unsigned int i=0; i<numItems; ++i)

if (data[i] > largest)

largest = data[i];

return largest;

}

With float.h and limit.h

-Programmers need to know the exactly type of T to derive the correct value of min()

With numeric_limits.h

-Programmers doesn’t need to know the type of T, only the compiler need to know

-The code will be resolved at compiling time so there is no overhead

Page 29: Advanced c++ ver 1.1

Example of trait technique

Same algorithm will not work optimally with every data structure

-Using traits can help you to choose “implementation details” of an algorithm for a specific object

- Suppose we have 2 kind of objects A, B that B has an optimized algorithm while A doesn’t

- How can we write an algorithm selector which chose the optimized algorithm for object B ?

//specialization of support optimized algorithm for object B

template<>

struct

supports_optimised <ObjectB >{

static const bool value = true;

};

class ObjectB {

public:

void optimised_implementation() {

//...

}

};

Page 30: Advanced c++ ver 1.1

Example of trait technique

//algorithm_selector

template< bool b >

struct selector{

template< typename T >

static void implement( T& object ){

//implement the alorithm operating on "object" here

}

};

template<>

struct algorithm_selector< true >{

template< typename T >

static void implementation( T& object ){

object.optimised_implementation();

}

};

template< typename T >

void algorithm( T& object ) {

selector<supports_optimised<T>::value>::implement(object);

}

int main(int argc, char* argv[]) {

ObjectA a;

algorithm( a );

// calls default implementation

ObjectB b;

algorithm( b );

// calls ObjectB::optimised_implementation();

return 0;

}

Proprietary & Confidential. ©Aricent Group 2011 30

Page 31: Advanced c++ ver 1.1

Example of trait technique

Suppose you need to write a database application and you find out that you need to write some wrapper functions around the primitive API

Typically, such APIs provide some fundamental of transferring raw data from a cursor to memory.

Our goal is write a high level function that extracts a value from a column without exposing all low-level details

Proprietary & Confidential. ©Aricent Group 2011 31

Page 32: Advanced c++ ver 1.1

Example of trait technique

// Example 1: Wrapping a raw cursor int fetch

// operation.

// Fetch an integer from the

// cursor "cr"

// at column "col"

// in the value "val"

void FetchIntField(db_cursor& cr,

unsigned int col,

int& val)

{

// Verify type match

if (cr.column_type[col] != DB_INTEGER)

throw std::runtime_error(

"Column type mismatch");

// Do the fetch

db_integer temp;

if (!db_access_column(&cr, col))

throw std::runtime_error(

"Cannot transfer data");

memcpy(&temp, cr.column_data[col],

sizeof(temp));

// Required by the DB API for cleanup

db_release_column(&cr, col);

// Convert from the database native type to int

val = static_cast<int>(temp);

}

Proprietary & Confidential. ©Aricent Group 2011

Page 33: Advanced c++ ver 1.1

Example of trait technique

// Wrapping a raw cursor int fetch operation.

// Fetch an integer from the cursor "cr”at column "col” in the value "val"

void FetchIntField(db_cursor& cr, unsigned int col, int& val){

// Verify type match

if (cr.column_type[col] != DB_INTEGER)

throw std::runtime_error("Column type mismatch");

// Do the fetch

db_integer temp;

if (!db_access_column(&cr, col))

throw std::runtime_error("Cannot transfer data");

memcpy(&temp, cr.column_data[col],sizeof(temp));

// Required by the DB API for cleanup

db_release_column(&cr, col);

// Convert from the database native type to int

val = static_cast<int>(temp);

}

Proprietary & Confidential. ©Aricent Group 2011

Page 34: Advanced c++ ver 1.1

Example of trait technique

//this is what define in the API header

#define DB_INTEGER 1

#define DB_STRING 2

#define DB_CURRENCY 3

...

typedef long int db_integer;

typedef char db_string[255];

typedef struct {

int integral_part;

unsigned char fractionary_part;

} db_currency;

What if we want to reuse the FetchIntField function for other types of data ?

Proprietary & Confidential. ©Aricent Group 2011

Page 35: Advanced c++ ver 1.1

Example of trait technique

// Defining DbTraits

// Most general case not implemented

template <typename T> struct DbTraits;

// Specialization for int

template <>

struct DbTraits<int>{

enum { TypeId = DB_INTEGER };

typedef db_integer DbNativeType;

static void Convert(DbNativeType from, int& to){

to = static_cast<int>(from);

}

};

// Defining DbTraits

// Specialization for double

template <>

struct DbTraits<double>{

enum { TypeId = DB_CURRENCY };

typedef db_currency DbNativeType;

static void

Convert(const DbNativeType& from, double& to){

to = from.integral_part + from.fractionary_part / 100.;

}

};

Proprietary & Confidential. ©Aricent Group 2011

Page 36: Advanced c++ ver 1.1

Example of trait technique

// A generic, extensible FetchField using DbTraits

//

template <class T>

void FetchField(db_cursor& cr, unsigned int col, T& val)

{

// Define the traits type

typedef DbTraits<T> Traits;

if (cr.column_type[col] != Traits::TypeId)

throw std::runtime_error("Column type mismatch");

if (!db_access_column(&cr, col))

throw std::runtime_error("Cannot transfer data");

typename Traits::DbNativeType temp;

memcpy(&temp, cr.column_data[col], sizeof(temp));

Traits::Convert(temp, val);

db_release_column(&cr, col);

}

Proprietary & Confidential. ©Aricent Group 2011 36

Page 37: Advanced c++ ver 1.1

SFINAE

What is SFINAE ?

Substitution Failure Is Not An Error

Please take a loot at the following code piece

int negate(int i){ return -i; }template <typename T>typename T::result_type negate(T const &t){    return -t();}

What will happen if we call negate(10) ?

Page 38: Advanced c++ ver 1.1

SFINAE

The first instantiation will be a perfect match and give us a result of -10

int negate(int i){ return -i; }

However, the compiler will also take the 2nd template into consideration and generating the following code

int::result_type negate(int const &t)

{

return -t();

}

This will cause an compiler error since int does not have a “result_type” but fortunately, this error will be silently ignore

Proprietary & Confidential. ©Aricent Group 2011

Page 39: Advanced c++ ver 1.1

SFINAE examples

Using SFINAE to determine if an object is a container

Refer to sfinae1.cpp

Using SFINAE to implement a supper print function

Super print function can print the content of the container

Refer to sfinae2.cpp

Proprietary & Confidential. ©Aricent Group 2011

Page 40: Advanced c++ ver 1.1

RAII

What wrong in the following piece of code ?

void foo()

{

File f;

f.open("boo.txt");

loadFromFile(f);

f.close();}

How can we fix it ?

Proprietary & Confidential. ©Aricent Group 2011

Page 41: Advanced c++ ver 1.1

RAII

RAII – Resource Acquisition Is Initialization

• Resource is acquired in the constructor and released in destructor

• Life of a resource is tied to a life of a local variable which is end when it goes out of scope

RAII consists of 3 parts

• The resource is acquired in the constructor (e.g. opening a file). This part is optional, but common.

• The resource is relinquished in the destructor (e.g. closing a file)

• Instances of the class are stack allocated (important – why ?)

Proprietary & Confidential. ©Aricent Group 2011

Page 42: Advanced c++ ver 1.1

Implementing RAII

class OpenFile {

public:

OpenFile(const char* filename){

//throws an exception on failure

_file.open(filename);

}

~OpenFile(){

_file.close();

}

std::string readLine() {

return _file.readLine();

}

private:

File _file;

};

void foo(){

// then we can use it like this

OpenFile f("boo.txt");

//exception safe, and no closing necessary

loadFromFile(f);

}

Proprietary & Confidential. ©Aricent Group 2011

Page 43: Advanced c++ ver 1.1

Why RAII need stack allocated ?

C++ guarantees that the destructors of objects on the stack will be called, even if an exception is thrown

Example:

std::string firstLineOf(const char* filename){ OpenFile f("boo.txt"); //stack allocated return f.readLine(); //File closed here. `f` goes out of scope and destructor is run.}

std::string firstLineOf(const char* filename){ OpenFile* f = new OpenFile("boo.txt"); //heap allocated return f->readLine(); //Destructor is never run, because `f` is never //deleted}

Proprietary & Confidential. ©Aricent Group 2011 43

Page 44: Advanced c++ ver 1.1

C++11 features

auto and decltype

lamda expression

unique_ptr and shared_ptr

rvalue reference

Proprietary & Confidential. ©Aricent Group 2011

Page 45: Advanced c++ ver 1.1

“The contents here are for Aricent Group internal training purposes only and do not carry any commercial value” 45Restricted ©Aricent Group 2011

Syntax

auto variable initializer

auto function -> return type

Explanation:

The type of the variable can be deduced from its initialization

Can be accompanied by modifiers (const or & …)

Example:

Instead of int x = 4;now you can write auto x = 4;

Auto is really shines when working with templates and iterator

The joy of auto

Page 46: Advanced c++ ver 1.1

The joy of auto

C++98

template <typename BuiltType, typename Builder>

void

makeAndProcessObject (const Builder& builder)

{

vector<int> v;

vector<int>::iterator itr = v.begin();

BuiltType val = builder.makeObject();

// do stuff with val

}

MyObjBuilder builder;

makeAndProcessObject<MyObj>( builder );

C++11

template <typename Builder>

void

makeAndProcessObject (const Builder& builder)

{

vector<int> v;

auto itr = v.begin();

auto val = builder.makeObject();

// do stuff with val

}

MyObjBuilder builder;

makeAndProcessObject( builder );

Page 47: Advanced c++ ver 1.1

decltype and new return value syntax

C++98

class Person

{

public:

enum PersonType { ADULT, CHILD, SENIOR };

void setPersonType (PersonType person_type);

PersonType getPersonType ();

private:

PersonType _person_type;

};

Person::PersonType Person::getPersonType ()

{

return _person_type;

}

C++11

class Person

{

public:

enum PersonType { ADULT, CHILD, SENIOR };

void setPersonType (PersonType person_type);

PersonType getPersonType ();

private:

PersonType _person_type;

};

auto Person::getPersonType () -> PersonType

{

return _person_type;

}

Proprietary & Confidential. ©Aricent Group 2011 47

Page 48: Advanced c++ ver 1.1

decltype and new return value syntax

template <typename Builder>

auto

makeAndProcessObject (const Builder& builder) -> decltype( builder.makeObject() )

{

auto val = builder.makeObject();

// do stuff with val

return val;

}

Proprietary & Confidential. ©Aricent Group 2011 48

Page 49: Advanced c++ ver 1.1

lambda expression

lambda expression enable the ability to write lambda function

lamda function is inline function (similar to functor or function pointer)

creating quick function is easier

Syntax

Proprietary & Confidential. ©Aricent Group 2011

[captures] (params) -> ret { statements; }

Optional, required only if lamda takes arguments

Optional, compiler automatically deduces the return type

Page 50: Advanced c++ ver 1.1

Variable captured with lambda

Proprietary & Confidential. ©Aricent Group 2011

[] Capture nothing

[&] Capture any referenced variable by reference

[=] Capture any referenced variable by making a copy

[=, &foo] Capture any referenced variable by making a copy, but capture variable foo by reference

[bar] Capture bar by making a copy; don't copy anything else

[this] Capture the this pointer of the enclosing class

Page 51: Advanced c++ ver 1.1

Lambda return type and exceptions

What is the return type of a lambda ?

[] () { return 1; } // compiler knows this returns an integer

// now we're telling the compiler what we want

// new return value syntax is the only way

[] () -> int { return 1; }

How can lambda function throw an exception ?

[]()throw(){ /* code that you don't expect to throw an exception*/ }

Example: refer to lambda1.cpp

Proprietary & Confidential. ©Aricent Group 2011

Page 52: Advanced c++ ver 1.1

Unique pointer

What is unique pointer ?

• Pointer that owns the object exclusively

• Responsible for deleting the object when

– Itself is destroyed

– Its value is changed (assignment operation or unique_ptr::reset)

• Support only move assignment

• Example: refer to uniqueptr.cpp

Proprietary & Confidential. ©Aricent Group 2011

Page 53: Advanced c++ ver 1.1

Shared pointer

What is shared pointer ?

• Take the ownership of a pointer and share that ownership

• The last pointer which release the ownership is responsible to delete the object

• shared_ptr release the ownership they co-own when

– Itself is destroyed

– Its value is changed by assignment operation or shared_ptr::reset()

• Shared_ptr can only share the ownership by copying their value (not initializing)

• Shared_ptr contains two pointer

– stored pointer, object they are pointing to and can be deference(*)

– owned pointer(possibly shared) points to the object which it’s holding the ownership

– Generally, stored pointer and owned pointer point to the same object

• Example: refer to sharedptr.cpp

Proprietary & Confidential. ©Aricent Group 2011

Page 54: Advanced c++ ver 1.1

rvalue

What is rvalue ?

In C, rvalue is an expression that can only appear on the right hand side of an assignment

Example:int a = 42;

int b = 43;

// a and b are both l-values:

a = b; // ok

b = a; // ok

a = a * b; // ok

// a * b is an rvalue:

int c = a * b; // ok, rvalue on right hand side of assignment

a * b = 42; // error, rvalue on left hand side of assignment

Proprietary & Confidential. ©Aricent Group 2011

Page 55: Advanced c++ ver 1.1

rvalue

In C++, the rvalue definition becomes

A lvalue is an expression that refers to a memory location and allow us to take the address of that memory allocation via operator &

A rvalue is an expression that is not a lvalue

Proprietary & Confidential. ©Aricent Group 2011

Page 56: Advanced c++ ver 1.1

example

lvalue

int x;

int& getRef ()

{

return x;

}

getRef() = 4;

rvalue

int x;

int getVal ()

{

return x;

}

getVal();

Proprietary & Confidential. ©Aricent Group 2011

Page 57: Advanced c++ ver 1.1

rvalue reference

Syntax:

const string&& name = getName(); // ok

string&& name = getName(); // also ok

Example:

string getName () { return "Nam";}

string me("Nam");

printMe (const String& str){cout << str;}//take lvalue as argument

printMe (String&& str){ cout << str;}//take ravalue reference as agurment

printMe(me);

printMe(getName());

rvalue reference is a reference to an object which is about to evaporate into air

rvalue solves 2 problems

• Direct forwarding

• Move constructorProprietary & Confidential. ©Aricent Group 2011 57

Page 58: Advanced c++ ver 1.1

The pain of copy

vector<int> doubleValues (const vector<int>& v){

vector<int> new_values;

for (auto itr = v.begin(), end_itr = v.end(); itr != end_itr; ++itr ){

new_values.push_back( 2 *(*itr ));

}

return new_values;

}

int main()

{

vector<int> v;

for ( int i = 0; i < 10; i++ ){

v.push_back( i );

}

v = doubleValues( v );

}

How many operation we have to do if vector size is 10000 ?

Proprietary & Confidential. ©Aricent Group 2011

Page 59: Advanced c++ ver 1.1

Move constructor and move assignment

Myclass(Myclass&& other): size(0), buf(nullptr)

{

// pilfer other’s resource

size=other.size;

buf=other.buf;

// reset other

other.size=0;

other.buf=nullptr;

}

Myclass& Myclass::operator=(Myclass&& other)

{

if (this!=&other)

{

// release the current object’s resources

delete[] buf;

size=0;

// pilfer other’s resource

size=other.size;

buf=other.buf;

// reset other

other.size=0;

other.buf=nullptr;

}

return *this;

}

Proprietary & Confidential. ©Aricent Group 2011

Page 60: Advanced c++ ver 1.1

Notes on using rvalue reference

Q: How to make an expression become a rvalue ?

A: Use std::move()

Q: Is rvalue reference always rvalue

A: If the referenced object has a name then its rvalue reference is a lvalue

Example :

Q: Should I write a function which return a rvalue ?

A: Probably not, because most of the cases you will end up in dangling reference (a case where the reference exists but the object that it refers to has been destroyed)

Proprietary & Confidential. ©Aricent Group 2011 60

Page 61: Advanced c++ ver 1.1

“The contents here are for Aricent Group internal training purposes only and do not carry any commercial value” 61Restricted ©Aricent Group 2011

Aricent Group makes no representations or warranties with respect to contents of these slides and the same are being provided “as is”.  The content/materials in the slides are of a general nature and are not intended to address the specific circumstances of any particular individual or entity.  The material may provide links to internet sites (for the convenience of users) over which Aricent Group has no control and for which Aricent Group assumes no responsibility for the availability or content of these external sites.  While the attempt has been to acknowledge sources of materials wherever traceable to an individual or an institution; any materials not specifically acknowledged is purely unintentional

Disclaimer

Page 62: Advanced c++ ver 1.1

Thank You