SlideShare a Scribd company logo
Andrey Upadyshev
Hot C++:

Rvalue References And
Move Semantics
Licensed under a CC BY-SA 4.0 License. Version of 2015.06.19
1
Overview
❖ Rvalue references!
❖ Move semantics!
❖ It’s well assisted!!
❖ More ways to shoot yourself in the foot
2
Rvalue References
3
Lvalue And Rvalue (how came from C)
• lvalue - may appear on the left hand side of an
assignment, represents storage region locator value, i.e.
evaluates to object identity.!
• All the rest is non-lvalue or rvalue (because can appear
on the right hand side of assignment only)
4
Lvalue And Rvalue, Example 1
int a = 42; // OK lvalue on left side of assignment!
int b = 43; // and rvalue on right side!
!
a = b; // OK, lvalue may be on any side of assignment!
b = a; // OK, lvalue may be on any side of assignment!
!
int c = a * b; // OK, rvalue on right side of assignment!
a * b = 42; // err, rvalue on left hand side of assignment
!
int *p = &i; // OK, i is an lvalue!
int *p1 = &43; // err, cannot take the address of an rvalue!
5
Value Categories (C++11)
• lvalue - is an expression that identifies a non-
temporary object!
• prvalue (pure rvalue) - is an expression that
identifies a temporary object or is a value not
associated with any object (C++03 rvalue)!
• Ex: The result of calling a function whose return
type is a value!
• xvalue - is an expression that identifies an "eXpiring"
object, that is, the object that may be moved from!
• Ex: The result of calling a function whose return
type is an rvalue reference
6
Simplified!
}rvalues
std::cout << &bar().member; // ?
Lvalue And Rvalue, Example 2
Foo& foo(); // `foo()` is lvalue

foo() = 42; // OK

std::cout << &foo(); // OK
Bar bar(); // `bar()` is prvalue

Bar && pub(); // `pub()` is xvalue

Bar b2 = bar(); // OK

bar() = b2; // cannot assign to an rvalue

std::cout << &bar(); // cannot take the address of an rvalue

std::cout << &pub(); // …
7
std::cout << &bar().member; // reference to a member of an rvalue

// is an rvalue!
Lvalue References
void foo(const Bar& bar); //[1]

Binds to lvalue and rvalue. Can not modify bar.!
void foo(Bar& bar); //[2]

Binds to lvalue only. Can modify bar. (Old Visual Studios binds
it to rvalue too. But this does not conform to the Standard)
8
Bar read_bar(const char *filename);
foo(read_bar(“bar.txt”)); ?
foo(read_bar(“bar.txt”)); // [1] => bar is const
Rvalue References
9
void foo(const Bar& bar); //[1]
Binds to lvalue and rvalue. Can not modify bar.!
void foo(Bar& bar); //[2]
Binds to lvalue only. Can modify bar.!
void foo(Bar && bar); //[3]
Binds to rvalue only. Takes precedence over lvalue overloads. Can
modify bar.!
void foo(const Bar && bar); //[4]
Binds to rvalue only. Takes precedence over lvalue overloads. Can not
modify bar. [Almost] has no useful meaning. Use const ref overload
instead.
foo(read_bar(“bar.txt”)); // [3] => bar is mutable!
Why Do I Need Them At All?
void foo(Bar && rv);!
❖ In short: to use move semantics!!
❖ Longer:!
❖ Because rvalue references bind to rvalue, they can be
used to extend the lifetime of a modifiable temporary
(an rvalue is a temporary, remember?).!
❖ You can do funny things with temporary, e.g. safely
steal any data you need from it (nobody cares, heh).
It’s called move semantics.
10
Move Semantics
11
Move Semantics In Example
Copying!
MemBuf lv = rv;
class MemBuf { void *m_data; size_t m_size; ... };
12
F1 23 4C DB 98 73 11 ...
rv
allocate
and copy
F1 23 4C DB 98 73 11 ...
lv contains a copy of rv's
content
lv
Moving!
MemBuf lv = std::move(rv);
F1 23 4C DB 98 73 11 ...
rv
lv
lv grabs (steals) content of rv
rv in moved-from state
X
Moved-From Objects
❖ Moving-from does not abolish destructing. The object’s destructor
is called anyway!!
❖ Moved-from object should be placed in a valid but unspecified
state, so it is safe to:!
❖ destroy it!
❖ assign one a new value (is assignable)!
❖ A type may provide more strong guaranty. E.g. STL’s smart
pointers guaranty that moved-from object is empty.
13
F1 23 4C DB 98 73 11 ...
rv
lv
X
Why Move Semantics?
The best possible performance for classes with expensive copy while
keeping the clear interface.!
❖ std::vector<HugeObject> performing bad in C++03:!
❖ Copies elements on insertion and even more on growing.!
❖ Can be passed around only wrapped with smart pointer.!
❖ So we used std::vector<std::shared_ptr<HugeObject>> or
boost::ptr_vector<HugeObject> to gain performance but got new problems:!
❖ Extra allocation and extra level of indirection (performance!)!
❖ Extra complexity!
❖ Doesn’t work smoothly with STL algorithms (OK, ptr_vector does)!
❖ Thanks to move semantics std::vector<HugeObject> become good in C++11
(finally!):!
❖ Elements are moved on insertion and on growing!
❖ No [smart] pointer involved overhead!
❖ Clear and simple, STL algorithms works perfect!
❖ Can be moved around
14
Why Move Semantics?
❖ Clearer interface for non-copyable but movable objects (like files,
threads etc):!
❖ std::auto_ptr<File> openFile(

const char *filename); // C++03!
❖ File openFile(const char *filename); // C++11
15
Adding Move Semantics To a Class
❖ There are two new special member functions:!
❖ Move constructor:

Foo::Foo(Foo && rv);!
❖ Move assignment operator:

Foo& operator= (Foo && rv);!
❖ Like copy ctor/assignment operator, but moves from its argument.
❖ The functions are compiler generated by default (use it!) but may be user
provided, explicitly defaulted or deleted.!
❖ Compiler uses similar rules as for copy ctor/copy assignment operator
generation.!
❖ Visual Studio before 2015 does not generate move ctor/move
assignment. You must do it manually.
16
Forcing Move Semantics
template<class T>

void swap_opt(T& a, T& b)

{

T tmp(a);

a = b;

b = tmp;

}!
Hm, copying…
std::move just casts lvalue to rvalue (no moving itself!) what allows a move semantics
to be used. Scott Meyers said that perhaps one should be called rvalue_cast
17
template<class T>

void swap_opt(T& a, T& b)

{ 

T tmp(std::move(a));

a = std::move(b);

b = std::move(tmp);

}!
Moving!!!
Let’s implement optimized swap that utilize move semantics.!
For simplicity, assume that it will be applied only to movable types.
Forcing move semantics leaves moved from objects behind, so must be uses carefully:!
std::string tmp("bla-bla");

std::string s(std::move(tmp));

std::cout << tmp; // Using of 'moved from' object (e.g. by mistake) for

// other then assigning. Undefined behavior for most types
It’s Well Assisted
18
Supported By STL
❖ C++11 STL is significantly extended to support rvalue references
and move semantics:!
❖ All containers and other types storing user types (pair, tuple,
future, function, smart pointers etc) are move-aware.!
❖ New algorithms: move, move_forward!
❖ New iterator adapter: move_iterator!
❖ Movable, non-copyable unique_ptr replaces flawy auto_ptr
(which is deprecated)!
❖ Optimized swap for movable types!
❖ New type traits
19
Ref Qualifiers
❖ Member functions can be specified with ref-qualifier & or &&, placed
after cv-qualifier:!
❖ const Foo& Bar::foo() const & { // [1]

return m_foo;

}
❖ Foo&& Bar::foo() && { // [2]

return std::move(m_foo); // `*this` is always

} // lvalue
❖ Allow to have different overloads for lvalue and rvalue (temporary).!
❖ No ref-qualifier means “whatever” (for backward compatibility)!
❖ A function with a ref-qualifier can not overload with a function without
one.
20
Perfect Forwarding & Forwarding
References
❖ Perfect forwarding is finally possible! !
❖ Thanks to forwarding (aka universal) references and new
reference collapsing rules:!
❖ template<class P1, class P2>

void create_foo(P1 && p1, P2 && p2) {

Foo foo(std::forward<P1>(p1),

std::forward<P2>(p2));

…

}
❖ Looks even better with variadic templates (not a sarcasm!)!
❖ It is a big topic for another meeting
21
Optimization
❖ Copy elision does elision of both copy and move
operations!
❖ When copy elision is not applicable, compiler prefers
moving over copying.
22
Special Member Functions
❖ Move constructor and move assignment operator aren’t generated if copy
constructor, copy assignment operator or destructor is explicitly declared.!
❖ Copy constructor and copy assignment operator aren't generated if move
constructor or move assignment operator is explicitly declared!
❖ Not supported before Visual Studio 2015!
❖ Rule of three become rule of five:

If a class defines one of the following it should probably explicitly define all five:!
•destructor!
•copy constructor!
•copy assignment operator!
•move constructor!
•move assignment operator
23
More Ways To Shoot Yourself In
The Foot
24
Named Rvalue Reference Is Not an Rvalue
Foo::Foo(Bar && bar)

: m_bar(bar) {} //[1] Is something wrong?
Named rvalue reference identifies an object => it is lvalue.

i.e. bar is copied unless move semantics is forced!
Foo::Foo(Bar && bar)

: m_bar(std::move(bar)) {} //[2] OK
Foo::Foo(Foo && rh)

: m_bar(rh.m_bar) {} //[3] copy, ref to lvalue member is an lvalue
Foo::Foo(Foo && rh)

: m_bar(std::move(rh.m_bar)) {} //[4] OK

// or

: m_bar(std::move(rh).m_bar) {} //[5] OK, ref to rvalue member is

// rvalue
25
Returning of Rvalue Reference
Foo && make_foo() { //[1] Is something wrong?

return Foo(42);

}
An rvalue reference is a reference. Returning a reference to a
local object is bad. Return by value instead!
Foo make_foo() { //[2] OK

return Foo(42);

}
Return rvalue reference only when you really know that you need this. A right
example is std::move:!
template<class T>

typename std::remove_reference<T>::type&& std::move(T && t) {

return static_cast<typename std::remove_reference<T>::type &&>(t);

}
26
❖ Applying std::move to a const object does
not activate move semantics! You quietly got
copy instead of move.!
❖ const Foo f = make_foo();

return Bar(std::move(f));

// Moving of `f` is blocked
❖ std::move does not remove object constness!
❖ No compilation error generated in such case.!
❖ Confusing unjustified behavior. One can write
something like safe_move to protect himself.
std::move And Const Objects
27
Move Semantics and RVO
28
struct Foo {…};
Foo make_foo1() {

Foo r(…);

return std::move(r);

}
Everything correct?!
RVO is blocked, r is moved or copied!
Foo make_foo1() {

Foo r(…);

return r;

}
RVO is applied, no move or copy
Move Semantics and RVO
29
struct Bar {…};
struct Foo {

Foo(const Bar& rh);

Foo(Bar && rh);

…

};
Foo make_foo2() {
Bar bar(…);
return bar;

}
Everything correct?!
Actually it is `return Foo(bar)`. bar is copied!
Foo make_foo2() {
Bar bar(…);
return std::move(bar);

}
Actually it is `return Foo(std::move(bar))`. bar is moved. We can’t get any better here
Move Semantics And Exception Safety
❖ // Huge object

struct Elephant {

Elephant(const Elephant& op);

Elephant(Elephant && op);

Elephant& operator= (const Elephant& op);

Elephant& operator= (Elephant && op);

…

};



std::vector<Elephant> all_elephants;

… // Heavily use it
❖ Does everything look good?!
30
Move Semantics And Exception Safety
For good reason STL containers may copy elements internally unless
ones' move constructor doesn't throw. Special traits are used:!
std::move_if_noexcept!
std::is_nothrow_move_constructible!
To get rid of copy, add noexcept to the move special functions (only
if function really doesn't throw, no cheating, please!):!
Elephant(Elephant && op) noexcept;
Note that noexcept is not supported in Visual Studio before 2015, use
macro like BOOST_NOEXCEPT (<boost/config/suffix.hpp>):!
Elephant(Elephant && op) BOOST_NOEXCEPT;
31
Useful Links
Alex Allain, Move semantics and rvalue references in C++11

http://www.cprogramming.com/c++11/rvalue-references-and-move-semantics-in-c++11.html!
Dave Abrahams, Exceptionally Moving!

http://web.archive.org/web/20130524084627/http://cpp-next.com/archive/2009/10/exceptionally-
moving/!
Stephan T. Lavavej, Don’t Help the Compiler

http://channel9.msdn.com/Events/GoingNative/2013/Don-t-Help-the-Compiler!
Andrzej Krzemieński, Ref-qualifiers

https://akrzemi1.wordpress.com/2014/06/02/ref-qualifiers/!
Max Galkin. C++ curiosities: one does not simply move a const object

http://yacoder.net/blog/2015/05/06/cpp-curiosities-one-does-not-simply-move-a-const-object/!
C++ Reference

http://en.cppreference.com/w/!
C++11 Standard (final plus minor editorial changes)!
http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2012/n3337.pdf
32
Questions?
33
I HAVE NO IDEA

WHAT’S GOING ON.

More Related Content

PDF
Hot C++: Rvalue References And Move Semantics
PDF
[OLD VERSION, SEE DESCRIPTION FOR THE NEWER VERSION LINK] Hot С++: Universal ...
PDF
Hot C++: New Style of Arguments Passing
PDF
Hot С++: Universal References And Perfect Forwarding
PDF
Where to type_std_move?
PDF
C++11: Rvalue References, Move Semantics, Perfect Forwarding
PDF
[C++] The Curiously Recurring Template Pattern: Static Polymorphsim and Expre...
PDF
Cpp17 and Beyond
Hot C++: Rvalue References And Move Semantics
[OLD VERSION, SEE DESCRIPTION FOR THE NEWER VERSION LINK] Hot С++: Universal ...
Hot C++: New Style of Arguments Passing
Hot С++: Universal References And Perfect Forwarding
Where to type_std_move?
C++11: Rvalue References, Move Semantics, Perfect Forwarding
[C++] The Curiously Recurring Template Pattern: Static Polymorphsim and Expre...
Cpp17 and Beyond

What's hot (20)

PDF
Regular types in C++
PPTX
PPT
Gentle introduction to modern C++
PPTX
C++ 11 Features
PPTX
Modern C++
PDF
Smart Pointers in C++
PPTX
Presentation 2nd
PPT
What's New in C++ 11?
PDF
Modern C++
PPTX
The Style of C++ 11
PDF
06 -working_with_strings
PPTX
C traps and pitfalls for C++ programmers
PPTX
C++11: Feel the New Language
PDF
String notes
PPTX
Introduction to c programming
PPTX
GNAT Pro User Day: Ada 2012, Ravenscar and SPARK running on an Atmel ARM M4 (...
PPTX
Summary of effective modern c++ item1 2
PDF
(5) cpp abstractions essential_operators
PPTX
Summary of C++17 features
PPTX
Strings
Regular types in C++
Gentle introduction to modern C++
C++ 11 Features
Modern C++
Smart Pointers in C++
Presentation 2nd
What's New in C++ 11?
Modern C++
The Style of C++ 11
06 -working_with_strings
C traps and pitfalls for C++ programmers
C++11: Feel the New Language
String notes
Introduction to c programming
GNAT Pro User Day: Ada 2012, Ravenscar and SPARK running on an Atmel ARM M4 (...
Summary of effective modern c++ item1 2
(5) cpp abstractions essential_operators
Summary of C++17 features
Strings
Ad

Similar to [OLD VERSION, SEE DESCRIPTION FOR NEWER VERSION LINK] Hot C++: Rvalue References And Move Semantics (20)

PDF
C++ references
PDF
C++11 talk
PPTX
C++11 move semantics
PPTX
Beginning direct3d gameprogrammingcpp02_20160324_jintaeks
PPTX
Elements of C++11
PDF
The C++ rvalue lifetime disaster. Arno Schödl ➠ CoreHard Autumn 2019
PDF
C++ 11 usage experience
PPTX
PPTX
Lecture 3, c++(complete reference,herbet sheidt)chapter-13
PDF
(4) cpp automatic arrays_pointers_c-strings
PDF
C++ Training
PPTX
2CPP13 - Operator Overloading
PDF
Milot Shala - C++ (OSCAL2014)
PPTX
C++11 - STL Additions
PPTX
Pointers in C++ object oriented programming
PPTX
Introduction to pointers in c plus plus .
DOCX
New microsoft office word document (2)
PPT
106da session5 c++
PDF
Cs tocpp a-somewhatshortguide
PDF
Memory Management with Java and C++
C++ references
C++11 talk
C++11 move semantics
Beginning direct3d gameprogrammingcpp02_20160324_jintaeks
Elements of C++11
The C++ rvalue lifetime disaster. Arno Schödl ➠ CoreHard Autumn 2019
C++ 11 usage experience
Lecture 3, c++(complete reference,herbet sheidt)chapter-13
(4) cpp automatic arrays_pointers_c-strings
C++ Training
2CPP13 - Operator Overloading
Milot Shala - C++ (OSCAL2014)
C++11 - STL Additions
Pointers in C++ object oriented programming
Introduction to pointers in c plus plus .
New microsoft office word document (2)
106da session5 c++
Cs tocpp a-somewhatshortguide
Memory Management with Java and C++
Ad

Recently uploaded (20)

PPTX
Computer Software and OS of computer science of grade 11.pptx
PDF
wealthsignaloriginal-com-DS-text-... (1).pdf
PPT
Introduction Database Management System for Course Database
PPTX
ai tools demonstartion for schools and inter college
PPTX
Agentic AI : A Practical Guide. Undersating, Implementing and Scaling Autono...
PPTX
VVF-Customer-Presentation2025-Ver1.9.pptx
PDF
Internet Downloader Manager (IDM) Crack 6.42 Build 42 Updates Latest 2025
PDF
Digital Systems & Binary Numbers (comprehensive )
PPTX
assetexplorer- product-overview - presentation
PDF
Odoo Companies in India – Driving Business Transformation.pdf
PDF
Wondershare Filmora 15 Crack With Activation Key [2025
PPTX
Transform Your Business with a Software ERP System
PDF
Navsoft: AI-Powered Business Solutions & Custom Software Development
PDF
SAP S4 Hana Brochure 3 (PTS SYSTEMS AND SOLUTIONS)
PPTX
CHAPTER 2 - PM Management and IT Context
PPTX
history of c programming in notes for students .pptx
PDF
Upgrade and Innovation Strategies for SAP ERP Customers
PDF
medical staffing services at VALiNTRY
PPTX
Embracing Complexity in Serverless! GOTO Serverless Bengaluru
PDF
Designing Intelligence for the Shop Floor.pdf
Computer Software and OS of computer science of grade 11.pptx
wealthsignaloriginal-com-DS-text-... (1).pdf
Introduction Database Management System for Course Database
ai tools demonstartion for schools and inter college
Agentic AI : A Practical Guide. Undersating, Implementing and Scaling Autono...
VVF-Customer-Presentation2025-Ver1.9.pptx
Internet Downloader Manager (IDM) Crack 6.42 Build 42 Updates Latest 2025
Digital Systems & Binary Numbers (comprehensive )
assetexplorer- product-overview - presentation
Odoo Companies in India – Driving Business Transformation.pdf
Wondershare Filmora 15 Crack With Activation Key [2025
Transform Your Business with a Software ERP System
Navsoft: AI-Powered Business Solutions & Custom Software Development
SAP S4 Hana Brochure 3 (PTS SYSTEMS AND SOLUTIONS)
CHAPTER 2 - PM Management and IT Context
history of c programming in notes for students .pptx
Upgrade and Innovation Strategies for SAP ERP Customers
medical staffing services at VALiNTRY
Embracing Complexity in Serverless! GOTO Serverless Bengaluru
Designing Intelligence for the Shop Floor.pdf

[OLD VERSION, SEE DESCRIPTION FOR NEWER VERSION LINK] Hot C++: Rvalue References And Move Semantics

  • 1. Andrey Upadyshev Hot C++:
 Rvalue References And Move Semantics Licensed under a CC BY-SA 4.0 License. Version of 2015.06.19 1
  • 2. Overview ❖ Rvalue references! ❖ Move semantics! ❖ It’s well assisted!! ❖ More ways to shoot yourself in the foot 2
  • 4. Lvalue And Rvalue (how came from C) • lvalue - may appear on the left hand side of an assignment, represents storage region locator value, i.e. evaluates to object identity.! • All the rest is non-lvalue or rvalue (because can appear on the right hand side of assignment only) 4
  • 5. Lvalue And Rvalue, Example 1 int a = 42; // OK lvalue on left side of assignment! int b = 43; // and rvalue on right side! ! a = b; // OK, lvalue may be on any side of assignment! b = a; // OK, lvalue may be on any side of assignment! ! int c = a * b; // OK, rvalue on right side of assignment! a * b = 42; // err, rvalue on left hand side of assignment ! int *p = &i; // OK, i is an lvalue! int *p1 = &43; // err, cannot take the address of an rvalue! 5
  • 6. Value Categories (C++11) • lvalue - is an expression that identifies a non- temporary object! • prvalue (pure rvalue) - is an expression that identifies a temporary object or is a value not associated with any object (C++03 rvalue)! • Ex: The result of calling a function whose return type is a value! • xvalue - is an expression that identifies an "eXpiring" object, that is, the object that may be moved from! • Ex: The result of calling a function whose return type is an rvalue reference 6 Simplified! }rvalues
  • 7. std::cout << &bar().member; // ? Lvalue And Rvalue, Example 2 Foo& foo(); // `foo()` is lvalue
 foo() = 42; // OK
 std::cout << &foo(); // OK Bar bar(); // `bar()` is prvalue
 Bar && pub(); // `pub()` is xvalue
 Bar b2 = bar(); // OK
 bar() = b2; // cannot assign to an rvalue
 std::cout << &bar(); // cannot take the address of an rvalue
 std::cout << &pub(); // … 7 std::cout << &bar().member; // reference to a member of an rvalue
 // is an rvalue!
  • 8. Lvalue References void foo(const Bar& bar); //[1]
 Binds to lvalue and rvalue. Can not modify bar.! void foo(Bar& bar); //[2]
 Binds to lvalue only. Can modify bar. (Old Visual Studios binds it to rvalue too. But this does not conform to the Standard) 8 Bar read_bar(const char *filename); foo(read_bar(“bar.txt”)); ? foo(read_bar(“bar.txt”)); // [1] => bar is const
  • 9. Rvalue References 9 void foo(const Bar& bar); //[1] Binds to lvalue and rvalue. Can not modify bar.! void foo(Bar& bar); //[2] Binds to lvalue only. Can modify bar.! void foo(Bar && bar); //[3] Binds to rvalue only. Takes precedence over lvalue overloads. Can modify bar.! void foo(const Bar && bar); //[4] Binds to rvalue only. Takes precedence over lvalue overloads. Can not modify bar. [Almost] has no useful meaning. Use const ref overload instead. foo(read_bar(“bar.txt”)); // [3] => bar is mutable!
  • 10. Why Do I Need Them At All? void foo(Bar && rv);! ❖ In short: to use move semantics!! ❖ Longer:! ❖ Because rvalue references bind to rvalue, they can be used to extend the lifetime of a modifiable temporary (an rvalue is a temporary, remember?).! ❖ You can do funny things with temporary, e.g. safely steal any data you need from it (nobody cares, heh). It’s called move semantics. 10
  • 12. Move Semantics In Example Copying! MemBuf lv = rv; class MemBuf { void *m_data; size_t m_size; ... }; 12 F1 23 4C DB 98 73 11 ... rv allocate and copy F1 23 4C DB 98 73 11 ... lv contains a copy of rv's content lv Moving! MemBuf lv = std::move(rv); F1 23 4C DB 98 73 11 ... rv lv lv grabs (steals) content of rv rv in moved-from state X
  • 13. Moved-From Objects ❖ Moving-from does not abolish destructing. The object’s destructor is called anyway!! ❖ Moved-from object should be placed in a valid but unspecified state, so it is safe to:! ❖ destroy it! ❖ assign one a new value (is assignable)! ❖ A type may provide more strong guaranty. E.g. STL’s smart pointers guaranty that moved-from object is empty. 13 F1 23 4C DB 98 73 11 ... rv lv X
  • 14. Why Move Semantics? The best possible performance for classes with expensive copy while keeping the clear interface.! ❖ std::vector<HugeObject> performing bad in C++03:! ❖ Copies elements on insertion and even more on growing.! ❖ Can be passed around only wrapped with smart pointer.! ❖ So we used std::vector<std::shared_ptr<HugeObject>> or boost::ptr_vector<HugeObject> to gain performance but got new problems:! ❖ Extra allocation and extra level of indirection (performance!)! ❖ Extra complexity! ❖ Doesn’t work smoothly with STL algorithms (OK, ptr_vector does)! ❖ Thanks to move semantics std::vector<HugeObject> become good in C++11 (finally!):! ❖ Elements are moved on insertion and on growing! ❖ No [smart] pointer involved overhead! ❖ Clear and simple, STL algorithms works perfect! ❖ Can be moved around 14
  • 15. Why Move Semantics? ❖ Clearer interface for non-copyable but movable objects (like files, threads etc):! ❖ std::auto_ptr<File> openFile(
 const char *filename); // C++03! ❖ File openFile(const char *filename); // C++11 15
  • 16. Adding Move Semantics To a Class ❖ There are two new special member functions:! ❖ Move constructor:
 Foo::Foo(Foo && rv);! ❖ Move assignment operator:
 Foo& operator= (Foo && rv);! ❖ Like copy ctor/assignment operator, but moves from its argument. ❖ The functions are compiler generated by default (use it!) but may be user provided, explicitly defaulted or deleted.! ❖ Compiler uses similar rules as for copy ctor/copy assignment operator generation.! ❖ Visual Studio before 2015 does not generate move ctor/move assignment. You must do it manually. 16
  • 17. Forcing Move Semantics template<class T>
 void swap_opt(T& a, T& b)
 {
 T tmp(a);
 a = b;
 b = tmp;
 }! Hm, copying… std::move just casts lvalue to rvalue (no moving itself!) what allows a move semantics to be used. Scott Meyers said that perhaps one should be called rvalue_cast 17 template<class T>
 void swap_opt(T& a, T& b)
 { 
 T tmp(std::move(a));
 a = std::move(b);
 b = std::move(tmp);
 }! Moving!!! Let’s implement optimized swap that utilize move semantics.! For simplicity, assume that it will be applied only to movable types. Forcing move semantics leaves moved from objects behind, so must be uses carefully:! std::string tmp("bla-bla");
 std::string s(std::move(tmp));
 std::cout << tmp; // Using of 'moved from' object (e.g. by mistake) for
 // other then assigning. Undefined behavior for most types
  • 19. Supported By STL ❖ C++11 STL is significantly extended to support rvalue references and move semantics:! ❖ All containers and other types storing user types (pair, tuple, future, function, smart pointers etc) are move-aware.! ❖ New algorithms: move, move_forward! ❖ New iterator adapter: move_iterator! ❖ Movable, non-copyable unique_ptr replaces flawy auto_ptr (which is deprecated)! ❖ Optimized swap for movable types! ❖ New type traits 19
  • 20. Ref Qualifiers ❖ Member functions can be specified with ref-qualifier & or &&, placed after cv-qualifier:! ❖ const Foo& Bar::foo() const & { // [1]
 return m_foo;
 } ❖ Foo&& Bar::foo() && { // [2]
 return std::move(m_foo); // `*this` is always
 } // lvalue ❖ Allow to have different overloads for lvalue and rvalue (temporary).! ❖ No ref-qualifier means “whatever” (for backward compatibility)! ❖ A function with a ref-qualifier can not overload with a function without one. 20
  • 21. Perfect Forwarding & Forwarding References ❖ Perfect forwarding is finally possible! ! ❖ Thanks to forwarding (aka universal) references and new reference collapsing rules:! ❖ template<class P1, class P2>
 void create_foo(P1 && p1, P2 && p2) {
 Foo foo(std::forward<P1>(p1),
 std::forward<P2>(p2));
 …
 } ❖ Looks even better with variadic templates (not a sarcasm!)! ❖ It is a big topic for another meeting 21
  • 22. Optimization ❖ Copy elision does elision of both copy and move operations! ❖ When copy elision is not applicable, compiler prefers moving over copying. 22
  • 23. Special Member Functions ❖ Move constructor and move assignment operator aren’t generated if copy constructor, copy assignment operator or destructor is explicitly declared.! ❖ Copy constructor and copy assignment operator aren't generated if move constructor or move assignment operator is explicitly declared! ❖ Not supported before Visual Studio 2015! ❖ Rule of three become rule of five:
 If a class defines one of the following it should probably explicitly define all five:! •destructor! •copy constructor! •copy assignment operator! •move constructor! •move assignment operator 23
  • 24. More Ways To Shoot Yourself In The Foot 24
  • 25. Named Rvalue Reference Is Not an Rvalue Foo::Foo(Bar && bar)
 : m_bar(bar) {} //[1] Is something wrong? Named rvalue reference identifies an object => it is lvalue.
 i.e. bar is copied unless move semantics is forced! Foo::Foo(Bar && bar)
 : m_bar(std::move(bar)) {} //[2] OK Foo::Foo(Foo && rh)
 : m_bar(rh.m_bar) {} //[3] copy, ref to lvalue member is an lvalue Foo::Foo(Foo && rh)
 : m_bar(std::move(rh.m_bar)) {} //[4] OK
 // or
 : m_bar(std::move(rh).m_bar) {} //[5] OK, ref to rvalue member is
 // rvalue 25
  • 26. Returning of Rvalue Reference Foo && make_foo() { //[1] Is something wrong?
 return Foo(42);
 } An rvalue reference is a reference. Returning a reference to a local object is bad. Return by value instead! Foo make_foo() { //[2] OK
 return Foo(42);
 } Return rvalue reference only when you really know that you need this. A right example is std::move:! template<class T>
 typename std::remove_reference<T>::type&& std::move(T && t) {
 return static_cast<typename std::remove_reference<T>::type &&>(t);
 } 26
  • 27. ❖ Applying std::move to a const object does not activate move semantics! You quietly got copy instead of move.! ❖ const Foo f = make_foo();
 return Bar(std::move(f));
 // Moving of `f` is blocked ❖ std::move does not remove object constness! ❖ No compilation error generated in such case.! ❖ Confusing unjustified behavior. One can write something like safe_move to protect himself. std::move And Const Objects 27
  • 28. Move Semantics and RVO 28 struct Foo {…}; Foo make_foo1() {
 Foo r(…);
 return std::move(r);
 } Everything correct?! RVO is blocked, r is moved or copied! Foo make_foo1() {
 Foo r(…);
 return r;
 } RVO is applied, no move or copy
  • 29. Move Semantics and RVO 29 struct Bar {…}; struct Foo {
 Foo(const Bar& rh);
 Foo(Bar && rh);
 …
 }; Foo make_foo2() { Bar bar(…); return bar;
 } Everything correct?! Actually it is `return Foo(bar)`. bar is copied! Foo make_foo2() { Bar bar(…); return std::move(bar);
 } Actually it is `return Foo(std::move(bar))`. bar is moved. We can’t get any better here
  • 30. Move Semantics And Exception Safety ❖ // Huge object
 struct Elephant {
 Elephant(const Elephant& op);
 Elephant(Elephant && op);
 Elephant& operator= (const Elephant& op);
 Elephant& operator= (Elephant && op);
 …
 };
 
 std::vector<Elephant> all_elephants;
 … // Heavily use it ❖ Does everything look good?! 30
  • 31. Move Semantics And Exception Safety For good reason STL containers may copy elements internally unless ones' move constructor doesn't throw. Special traits are used:! std::move_if_noexcept! std::is_nothrow_move_constructible! To get rid of copy, add noexcept to the move special functions (only if function really doesn't throw, no cheating, please!):! Elephant(Elephant && op) noexcept; Note that noexcept is not supported in Visual Studio before 2015, use macro like BOOST_NOEXCEPT (<boost/config/suffix.hpp>):! Elephant(Elephant && op) BOOST_NOEXCEPT; 31
  • 32. Useful Links Alex Allain, Move semantics and rvalue references in C++11
 http://www.cprogramming.com/c++11/rvalue-references-and-move-semantics-in-c++11.html! Dave Abrahams, Exceptionally Moving!
 http://web.archive.org/web/20130524084627/http://cpp-next.com/archive/2009/10/exceptionally- moving/! Stephan T. Lavavej, Don’t Help the Compiler
 http://channel9.msdn.com/Events/GoingNative/2013/Don-t-Help-the-Compiler! Andrzej Krzemieński, Ref-qualifiers
 https://akrzemi1.wordpress.com/2014/06/02/ref-qualifiers/! Max Galkin. C++ curiosities: one does not simply move a const object
 http://yacoder.net/blog/2015/05/06/cpp-curiosities-one-does-not-simply-move-a-const-object/! C++ Reference
 http://en.cppreference.com/w/! C++11 Standard (final plus minor editorial changes)! http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2012/n3337.pdf 32
  • 33. Questions? 33 I HAVE NO IDEA
 WHAT’S GOING ON.

Editor's Notes

  • #2: Greeting to Ray, listeners friends and colleagues Who I'm , What I’m, Notify about first time and language - Notify about regalement - Notify to write slide number to refer in questions - Very quickly about first and second topics in general and whom it addressed to
  • #3: more details about presentation itself and whom it addressed to
  • #7: How many value categories do you know in C++11? 0? 2? more?
  • #8: QUIZ, is it compiles OK?
  • #9: QUIZ: 1 or 2 will be called?
  • #18: QUIZ, something wrong?
  • #21: Who know what is ref qualifier?
  • #22: Who knows, what is a universal reference?
  • #26: QUIZ: What is wrong? How to fix this?
  • #27: Is something wrong?
  • #29: Who knows what RVO means? Who knows what NRVO means?