Escolar Documentos
Profissional Documentos
Cultura Documentos
bit.ly/NVIDIA_Cpp_Topics
Scott Meyers, Software Development Consultant Kalb for NVIDIA Copyrighted material,
http://www.aristeia.com/ http://cpp.training/ all rights reserved.
Topics From Effective C++ Programming
Scott Meyers, Software Development Consultant Kalb for NVIDIA Copyrighted material,
http://www.aristeia.com/ http://cpp.training/ all rights reserved.
Topics From Effective C++ Programming
Jon Kalb
• 25 years of professional C++ development
• Chair of
•CppCon
•C++Now
•Silicon Valley Code Camp C++ Track
•Boost Steering Committee
• Taught C++ at Golden Gate University Grad School
• Co-Author of “C++ Today: The Beast is Back”
• Microsoft MVP
• jon@cpp.training
• @_JonKalb
• linkedin.com/in/jonkalb
Agenda
§ Type deduction
§ Initialization
§ const
§ Range based for loops
§ Introduction to Rvalue References and Move Semantics
§ Type fundamentals / Special member functions
§ Move Semantics and Perfect Forwarding Best Practices
§ STL / Algorithms / Containers
§ Generalized Function Objects
§ Lambda expressions
§ RAII and Smart Pointers
§ Efficiency
§ That’s a lot of topics.
Æ There may not be time to cover everything.
w We’ll definitely cover the most important material.
Scott Meyers, Software Development Consultant Kalb for NVIDIA Copyrighted material, all rights reserved.
http://www.aristeia.com/ http://cpp.training/ Slide 7
Scott Meyers, Software Development Consultant Kalb for NVIDIA Copyrighted material,
http://www.aristeia.com/ http://cpp.training/ all rights reserved.
Topics From Effective C++ Programming
Scott Meyers, Software Development Consultant Kalb for NVIDIA Copyrighted material, all rights reserved.
http://www.aristeia.com/ http://cpp.training/ Slide 8
Course Approach
Based on guidelines:
§ Guidelines are a lot easier to remember than the ISO standard.
§ You have to understand the rationale behind the guidelines.
§ Guidelines emphasize what you should do, not what you shouldn’t do.
Code examples are only fragments:
§ Most parts of a program are dull.
§ Fragments isolate important concepts, focus your attention.
§ Complete programs span multiple slides.
Æ Awkward for both instructor and student.
Scott Meyers, Software Development Consultant Kalb for NVIDIA Copyrighted material, all rights reserved.
http://www.aristeia.com/ http://cpp.training/ Slide 9
Scott Meyers, Software Development Consultant Kalb for NVIDIA Copyrighted material,
http://www.aristeia.com/ http://cpp.training/ all rights reserved.
Topics From Effective C++ Programming
Scott Meyers, Software Development Consultant Kalb for NVIDIA Copyrighted material, all rights reserved.
http://www.aristeia.com/ http://cpp.training/ Slide 10
Scott Meyers, Software Development Consultant Kalb for NVIDIA Copyrighted material,
http://www.aristeia.com/ http://cpp.training/ all rights reserved.
Topics From Effective C++ Programming
Why?
Why bother?
§ The specification for Modern C++ is twice as long as for Classic C++.
o Classic C++ is complicated enough.
§ Modern C++ is a moving target, there will always be something new to
learn.
§ Classic C++ is Turing complete.
o Any program that can be written can be written in C++98.
Scott Meyers, Software Development Consultant Kalb for NVIDIA Copyrighted material, all rights reserved.
http://www.aristeia.com/ http://cpp.training/ Slide 12
Why?
Why do we program in C++?
§ Power type deduction
o Low-level control uniform initialization
o High-level abstractions const
o Clarity and expressivity range-based for loops
o No compromise on performance moving & forwarding
§ More! More! More! type fundamentals
o Modern C++ gives us more of all of these STL, algorithms, cont.
o Convenience: fewer places for bugs to hide lambdas
o Also better safety generalized func. obj.
o Type safety smart pointers.
efficiency
o Resource management
Scott Meyers, Software Development Consultant Kalb for NVIDIA Copyrighted material, all rights reserved.
http://www.aristeia.com/ http://cpp.training/ Slide 13
Scott Meyers, Software Development Consultant Kalb for NVIDIA Copyrighted material,
http://www.aristeia.com/ http://cpp.training/ all rights reserved.
Topics From Effective C++ Programming
A Code Example
int const y(5); int const y{5};
int const x = 5; int const x{5};
int arr[] = { 5, 10, 15 }; int arr[]{ 5, 10, 15 };
struct Point1 { int x, y; }; struct Point1 { int x, y; };
Point1 const p1 = { 10, 20 }; Point1 const p1{ 10, 20 };
struct Point2 { struct Point2 {
Point2(int x, int y); Point2(int x, int y);
… …
}; };
Point2 const p2(10, 20); Point2 const p2{10, 20};
Scott Meyers, Software Development Consultant Kalb for NVIDIA Copyrighted material, all rights reserved.
http://www.aristeia.com/ http://cpp.training/ Slide 14
Scott Meyers, Software Development Consultant Kalb for NVIDIA Copyrighted material,
http://www.aristeia.com/ http://cpp.training/ all rights reserved.
Topics From Effective C++ Programming
initializer list
eliminates
initializing array
Another Code Example
int main() {
std::map<std::string, double> mean_temp{ {"California", 59.4},
{"Alaska", 26.6},
{"Hawaii", 70.0}};
for (auto t: mean_temp) { for each loop
std::cout << t.first << " (" << t.second << " F)\n";
}
auto type deduction
std::for_each(begin(mean_temp), end(mean_temp),
[] (auto& p) {p.second = (p.second - 32) * 5 / 9;});
lambda eliminates
for (auto t: mean_temp) { function object
std::cout << t.first << " (" << t.second << " C)\n";
}
}
Scott Meyers, Software Development Consultant Kalb for NVIDIA Copyrighted material,
http://www.aristeia.com/ http://cpp.training/ all rights reserved.
Topics From Effective C++ Programming
Type Deduction
Scott Meyers, Software Development Consultant Kalb for NVIDIA Copyrighted material, all rights reserved.
http://www.aristeia.com/ http://cpp.training/ Slide 18
Scott Meyers, Software Development Consultant Kalb for NVIDIA Copyrighted material,
http://www.aristeia.com/ http://cpp.training/ all rights reserved.
Topics From Effective C++ Programming
int i0(42);
int const i1(i0);
int& i2(i0);
int const& i3(i0);
f(i0); // deduce t’s type as int
f(i1); // deduce t’s type as int
f(i2); // deduce t’s type as int
f(i3); // deduce t’s type as int
For variables not explicitly declared to be a reference:
§ Top-level consts/volatiles in the initializing type are ignored.
int i0(42);
int const i1(i0);
int& i2(i0);
int const& i3(i0);
f(i0); // deduce t’s type as int&
f(i1); // deduce t’s type as int const&
f(i2); // deduce t’s type as int&
f(i3); // deduce t’s type as int const&
For variables explicitly declared to be a reference:
§ Top-level consts/volatiles in the initializing type cannot be ignored.
Scott Meyers, Software Development Consultant Kalb for NVIDIA Copyrighted material,
http://www.aristeia.com/ http://cpp.training/ all rights reserved.
Topics From Effective C++ Programming
Scott Meyers, Software Development Consultant Kalb for NVIDIA Copyrighted material, all rights reserved.
http://www.aristeia.com/ http://cpp.training/ Slide 22
Scott Meyers, Software Development Consultant Kalb for NVIDIA Copyrighted material, all rights reserved.
http://www.aristeia.com/ http://cpp.training/ Slide 23
Scott Meyers, Software Development Consultant Kalb for NVIDIA Copyrighted material,
http://www.aristeia.com/ http://cpp.training/ all rights reserved.
Topics From Effective C++ Programming
Scott Meyers, Software Development Consultant Kalb for NVIDIA Copyrighted material, all rights reserved.
http://www.aristeia.com/ http://cpp.training/ Slide 24
Scott Meyers, Software Development Consultant Kalb for NVIDIA Copyrighted material, all rights reserved.
http://www.aristeia.com/ http://cpp.training/ Slide 25
Scott Meyers, Software Development Consultant Kalb for NVIDIA Copyrighted material,
http://www.aristeia.com/ http://cpp.training/ all rights reserved.
Topics From Effective C++ Programming
What is “explicit”
Imagine a rational number type:
struct Rational
{
Rational(int num = 0, int den = 1); // Initial value
…
};
Rational operator+(Rational const&, Rational const&);
…
Rational r0, r1;
…
r0 = r1 + 6; // Do we want this to compile?
As written, this will compile.
What is “explicit”
Imagine a container type:
template<class T> struct Vector
{
Vector(int num = 0); // Initial size
…
};
…
int Mean(Vector<int> const&); // Calcs average
…
Mean(7); // Do we want this to compile?
Scott Meyers, Software Development Consultant Kalb for NVIDIA Copyrighted material,
http://www.aristeia.com/ http://cpp.training/ all rights reserved.
Topics From Effective C++ Programming
What is “explicit”
Imagine a container type:
template<class T> struct Vector
{
explicit Vector(int num = 0); // Initial size
…
}; Declaring the constructor explicit, means that …
…
int Mean(Vector<int> const&); // Calcs average
…
Mean(7);
… this will not compile.
What is “explicit”
Imagine a container type:
template<class T> struct Vector
{
explicit Vector(int num = 0); // Initial size
…
}; Declaring the constructor explicit, means that …
…
int Mean(Vector<int> const&); // Calcs average
…
Mean(Vector<int>(7) ); … the constructor can be used only if
the type name is explicitly stated.
Scott Meyers, Software Development Consultant Kalb for NVIDIA Copyrighted material,
http://www.aristeia.com/ http://cpp.training/ all rights reserved.
Topics From Effective C++ Programming
What is “explicit”
Any (non-copy) constructor that can be called with only one parameter is a
conversion constructor. This is true whether the constructor
• has only one parameter, or
• there are default values for all but (at most) one parameter.
Initialization
Uniform Initialization
Initializer Lists
Scott Meyers, Software Development Consultant Kalb for NVIDIA Copyrighted material, all rights reserved.
http://www.aristeia.com/ http://cpp.training/ Slide 31
Scott Meyers, Software Development Consultant Kalb for NVIDIA Copyrighted material,
http://www.aristeia.com/ http://cpp.training/ all rights reserved.
Topics From Effective C++ Programming
Scott Meyers, Software Development Consultant Kalb for NVIDIA Copyrighted material, all rights reserved.
http://www.aristeia.com/ http://cpp.training/ Slide 32
Initialization in C++98
Containers require another container:
int vals[] = { 10, 20, 30 };
std::vector<int> const cv(vals, vals+3); // init from another
// container
Member and heap arrays are impossible:
struct Widget {
Widget(): data(???) {}
private:
int const data[5]; // not initializable
};
float const* pData = new float const[4]; // not initializable
Scott Meyers, Software Development Consultant Kalb for NVIDIA Copyrighted material, all rights reserved.
http://www.aristeia.com/ http://cpp.training/ Slide 33
Scott Meyers, Software Development Consultant Kalb for NVIDIA Copyrighted material,
http://www.aristeia.com/ http://cpp.training/ all rights reserved.
Topics From Effective C++ Programming
Scott Meyers, Software Development Consultant Kalb for NVIDIA Copyrighted material, all rights reserved.
http://www.aristeia.com/ http://cpp.training/ Slide 34
Scott Meyers, Software Development Consultant Kalb for NVIDIA Copyrighted material, all rights reserved.
http://www.aristeia.com/ http://cpp.training/ Slide 35
Scott Meyers, Software Development Consultant Kalb for NVIDIA Copyrighted material,
http://www.aristeia.com/ http://cpp.training/ all rights reserved.
Topics From Effective C++ Programming
Scott Meyers, Software Development Consultant Kalb for NVIDIA Copyrighted material, all rights reserved.
http://www.aristeia.com/ http://cpp.training/ Slide 36
Brace-Initializing Aggregates
Initialize members/elements beginning-to-end.
§ Too many initializers ⇒ error.
§ Too few initializers ⇒ remaining objects are value-initialized:
Æ Built-in
types initialized to 0.
Æ UDTs with constructors are default-constructed.
Æ UDTs without constructors: members are value-initialized.
struct Point1 { int x, y; }; // as before
Point1 const p1 = { 10 }; // same as { 10, 0 }
Point1 const p2 = { 1, 2, 3 }; // error! too many
// initializers
Æ std::array is also an aggregate:
long f();
std::array<long, 3> arr = { 1, 2, f(), 4, 5 }; // error! too many
// initializers
Scott Meyers, Software Development Consultant Kalb for NVIDIA Copyrighted material, all rights reserved.
http://www.aristeia.com/ http://cpp.training/ Slide 37
Scott Meyers, Software Development Consultant Kalb for NVIDIA Copyrighted material,
http://www.aristeia.com/ http://cpp.training/ all rights reserved.
Topics From Effective C++ Programming
Brace-Initializing Non-Aggregates
Invoke a constructor.
struct Point2 { // as before
Point2(int x, int y);
…
};
short a, b;
…
Point2 const p1 {a, b}; // same as p1(a, b)
Point2 const p2 {10}; // error! too few ctor args
Point2 const p3 {5, 10, 20}; // error! too many ctor args
§ True even for containers (details shortly):
std::vector<int> v { 1, a, 2, b, 3 }; // calls a vector ctor
std::unordered_set<float> s { 0, 1.5, 3 }; // calls an
// unordered_set ctor
Scott Meyers, Software Development Consultant Kalb for NVIDIA Copyrighted material, all rights reserved.
http://www.aristeia.com/ http://cpp.training/ Slide 38
Scott Meyers, Software Development Consultant Kalb for NVIDIA Copyrighted material, all rights reserved.
http://www.aristeia.com/ http://cpp.training/ Slide 39
Scott Meyers, Software Development Consultant Kalb for NVIDIA Copyrighted material,
http://www.aristeia.com/ http://cpp.training/ all rights reserved.
Topics From Effective C++ Programming
Scott Meyers, Software Development Consultant Kalb for NVIDIA Copyrighted material, all rights reserved.
http://www.aristeia.com/ http://cpp.training/ Slide 40
Scott Meyers, Software Development Consultant Kalb for NVIDIA Copyrighted material, all rights reserved.
http://www.aristeia.com/ http://cpp.training/ Slide 41
Scott Meyers, Software Development Consultant Kalb for NVIDIA Copyrighted material,
http://www.aristeia.com/ http://cpp.training/ all rights reserved.
Topics From Effective C++ Programming
Scott Meyers, Software Development Consultant Kalb for NVIDIA Copyrighted material, all rights reserved.
http://www.aristeia.com/ http://cpp.training/ Slide 42
Scott Meyers, Software Development Consultant Kalb for NVIDIA Copyrighted material, all rights reserved.
http://www.aristeia.com/ http://cpp.training/ Slide 43
Scott Meyers, Software Development Consultant Kalb for NVIDIA Copyrighted material,
http://www.aristeia.com/ http://cpp.training/ all rights reserved.
Topics From Effective C++ Programming
Scott Meyers, Software Development Consultant Kalb for NVIDIA Copyrighted material, all rights reserved.
http://www.aristeia.com/ http://cpp.training/ Slide 44
Initializer Lists
A mechanism to generalize array aggregate initialization:
§ Available to all UDTs.
int x, y;
…
int a[] { x, y, 7, 22, -13, 44 }; // array initialization
std::vector<int> v { 99, -8, x-y, x*x }; // std. library type
Widget w { a[0]+a[1], x, 25, 16 }; // arbitrary UDT
§ Available for more than just initialization, e.g.
std::vector<int> v {}; // initialization
v.insert(v.end(), { 99, 88, -1, 15 }); // multi-element insertion
v = { 0, 1, x, y }; // replace v’s value
Æ Any function can use an “initializer” list.
Scott Meyers, Software Development Consultant Kalb for NVIDIA Copyrighted material, all rights reserved.
http://www.aristeia.com/ http://cpp.training/ Slide 45
Scott Meyers, Software Development Consultant Kalb for NVIDIA Copyrighted material,
http://www.aristeia.com/ http://cpp.training/ all rights reserved.
Topics From Effective C++ Programming
Initializer Lists
Approach startlingly simple:
§ Brace initializer lists convertible to std::initializer_list objects.
§ Functions can declare parameters of this type.
§ std::initializer_list stores initializer values in an array and offers these
member functions:
Æ size // # of elements in the array
Æ begin // ptr to first array element
Æ end // ptr to one-beyond-last array element
Scott Meyers, Software Development Consultant Kalb for NVIDIA Copyrighted material, all rights reserved.
http://www.aristeia.com/ http://cpp.training/ Slide 46
Initializer Lists
#include <initializer_list> // necessary header
std::u16string getName(int ID); // lookup name with given ID
struct Widget {
Widget(std::initializer_list<int> nameIDs)
{
names.reserve(nameIDs.size());
for (auto id: nameIDs) names.push_back(getName(id));
}
private:
std::vector<std::u16string> names;
};
...
Widget w { a[0]+a[1], x, 25, 16 }; // copies values into an array
// wrapped by an initializer_list
// passed to the Widget ctor.
Scott Meyers, Software Development Consultant Kalb for NVIDIA Copyrighted material, all rights reserved.
http://www.aristeia.com/ http://cpp.training/ Slide 47
Scott Meyers, Software Development Consultant Kalb for NVIDIA Copyrighted material,
http://www.aristeia.com/ http://cpp.training/ all rights reserved.
Topics From Effective C++ Programming
Initializer Lists
std::initializer_list parameters may be used with other parameters:
struct Widget {
Widget( std::string const& name, double epsilon,
std::initializer_list<int> il);
…
};
std::string name("Buffy");
Widget w {name, 0.5, // same as
{5, 10, 15} }; // Widget w(name, 0.5,
// std::initializer_list({5,10,15}));
§ Note the nested brace sets.
Scott Meyers, Software Development Consultant Kalb for NVIDIA Copyrighted material, all rights reserved.
http://www.aristeia.com/ http://cpp.training/ Slide 48
Initializer Lists
They may be templatized:
struct Widget {
template<class T> Widget(std::initializer_list<T> il);
...
};
...
Widget w1 { -55, 25, 16 }; // fine, T = int
Only homogeneous initializer lists allow type deduction to succeed:
Widget w2 { -55, 2.5, 16 }; // error, T can’t be deduced
Scott Meyers, Software Development Consultant Kalb for NVIDIA Copyrighted material, all rights reserved.
http://www.aristeia.com/ http://cpp.training/ Slide 49
Scott Meyers, Software Development Consultant Kalb for NVIDIA Copyrighted material,
http://www.aristeia.com/ http://cpp.training/ all rights reserved.
Topics From Effective C++ Programming
Scott Meyers, Software Development Consultant Kalb for NVIDIA Copyrighted material, all rights reserved.
http://www.aristeia.com/ http://cpp.training/ Slide 50
Scott Meyers, Software Development Consultant Kalb for NVIDIA Copyrighted material, all rights reserved.
http://www.aristeia.com/ http://cpp.training/ Slide 51
Scott Meyers, Software Development Consultant Kalb for NVIDIA Copyrighted material,
http://www.aristeia.com/ http://cpp.training/ all rights reserved.
Topics From Effective C++ Programming
Scott Meyers, Software Development Consultant Kalb for NVIDIA Copyrighted material, all rights reserved.
http://www.aristeia.com/ http://cpp.training/ Slide 52
Scott Meyers, Software Development Consultant Kalb for NVIDIA Copyrighted material, all rights reserved.
http://www.aristeia.com/ http://cpp.training/ Slide 53
Scott Meyers, Software Development Consultant Kalb for NVIDIA Copyrighted material,
http://www.aristeia.com/ http://cpp.training/ all rights reserved.
Topics From Effective C++ Programming
auto v1{expr};
We’ll cover decltype in a
auto x1{3}; // decltype(x1) is int later section.
auto x2{1, 2}; // error: not a single element
auto x3 = {3}; // decltype(x3) is std::initializer_list<int>
auto x4 = {1, 2}; // decltype(x4) is std::initializer_list<int>
auto x5 = {1, 2.0}; // error: cannot deduce element type
Scott Meyers, Software Development Consultant Kalb for NVIDIA Copyrighted material, all rights reserved.
http://www.aristeia.com/ http://cpp.training/ Slide 55
Scott Meyers, Software Development Consultant Kalb for NVIDIA Copyrighted material,
http://www.aristeia.com/ http://cpp.training/ all rights reserved.
Topics From Effective C++ Programming
Scott Meyers, Software Development Consultant Kalb for NVIDIA Copyrighted material, all rights reserved.
http://www.aristeia.com/ http://cpp.training/ Slide 56
Scott Meyers, Software Development Consultant Kalb for NVIDIA Copyrighted material, all rights reserved.
http://www.aristeia.com/ http://cpp.training/ Slide 57
Scott Meyers, Software Development Consultant Kalb for NVIDIA Copyrighted material,
http://www.aristeia.com/ http://cpp.training/ all rights reserved.
Topics From Effective C++ Programming
const
Scott Meyers, Software Development Consultant Kalb for NVIDIA Copyrighted material, all rights reserved.
http://www.aristeia.com/ http://cpp.training/ Slide 58
Scott Meyers, Software Development Consultant Kalb for NVIDIA Copyrighted material, all rights reserved.
http://www.aristeia.com/ http://cpp.training/ Slide 59
Scott Meyers, Software Development Consultant Kalb for NVIDIA Copyrighted material,
http://www.aristeia.com/ http://cpp.training/ all rights reserved.
Topics From Effective C++ Programming
Scott Meyers, Software Development Consultant Kalb for NVIDIA Copyrighted material, all rights reserved.
http://www.aristeia.com/ http://cpp.training/ Slide 60
Scott Meyers, Software Development Consultant Kalb for NVIDIA Copyrighted material, all rights reserved.
http://www.aristeia.com/ http://cpp.training/ Slide 61
Scott Meyers, Software Development Consultant Kalb for NVIDIA Copyrighted material,
http://www.aristeia.com/ http://cpp.training/ all rights reserved.
Topics From Effective C++ Programming
const Syntax
The rule for how const is applied is:
• The const always applies to what is to its left.
• Unless nothing is to its left, then it applies to what is on the right
char greeting[ ]{"Hello"};
Scott Meyers, Software Development Consultant Kalb for NVIDIA Copyrighted material, all rights reserved.
http://www.aristeia.com/ http://cpp.training/ Slide 62
const Syntax
The rule for how const is applied is:
• The const always applies to what is to its left.
• Unless nothing is to its left, then it applies to what is on the right
char greeting[ ]{"Hello"};
Scott Meyers, Software Development Consultant Kalb for NVIDIA Copyrighted material,
http://www.aristeia.com/ http://cpp.training/ all rights reserved.
Topics From Effective C++ Programming
Scott Meyers, Software Development Consultant Kalb for NVIDIA Copyrighted material, all rights reserved.
http://www.aristeia.com/ http://cpp.training/ Slide 65
Scott Meyers, Software Development Consultant Kalb for NVIDIA Copyrighted material, all rights reserved.
http://www.aristeia.com/ http://cpp.training/ Slide 66
Scott Meyers, Software Development Consultant Kalb for NVIDIA Copyrighted material,
http://www.aristeia.com/ http://cpp.training/ all rights reserved.
Topics From Effective C++ Programming
Scott Meyers, Software Development Consultant Kalb for NVIDIA Copyrighted material, all rights reserved.
http://www.aristeia.com/ http://cpp.training/ Slide 67
Scott Meyers, Software Development Consultant Kalb for NVIDIA Copyrighted material, all rights reserved.
http://www.aristeia.com/ http://cpp.training/ Slide 68
Scott Meyers, Software Development Consultant Kalb for NVIDIA Copyrighted material,
http://www.aristeia.com/ http://cpp.training/ all rights reserved.
Topics From Effective C++ Programming
Scott Meyers, Software Development Consultant Kalb for NVIDIA Copyrighted material, all rights reserved.
http://www.aristeia.com/ http://cpp.training/ Slide 69
Scott Meyers, Software Development Consultant Kalb for NVIDIA Copyrighted material, all rights reserved.
http://www.aristeia.com/ http://cpp.training/ Slide 70
Scott Meyers, Software Development Consultant Kalb for NVIDIA Copyrighted material,
http://www.aristeia.com/ http://cpp.training/ all rights reserved.
Topics From Effective C++ Programming
Scott Meyers, Software Development Consultant Kalb for NVIDIA Copyrighted material, all rights reserved.
http://www.aristeia.com/ http://cpp.training/ Slide 72
Scott Meyers, Software Development Consultant Kalb for NVIDIA Copyrighted material, all rights reserved.
http://www.aristeia.com/ http://cpp.training/ Slide 73
Scott Meyers, Software Development Consultant Kalb for NVIDIA Copyrighted material,
http://www.aristeia.com/ http://cpp.training/ all rights reserved.
Topics From Effective C++ Programming
Rvalue semantics
Will this compile?:
int a{1};
int b{2};
int c{3};
a + b = c;
The compiler will not allow us to modify temporaries (rvalues) of
fundament types.
Rvalue semantics
Return-by-value is often useful:
§ It allows for complicated expressions.
Arithmetic operators are a good example:
struct UPInt { ... }; // "unlimited precision integers"
UPInt operator+(UPInt const& lhs, UPInt const& rhs);
UPInt operator/(UPInt const& lhs, UPInt const & rhs);
UPInt a, b, c;
...
c = (a + b) / b; // same as
// c.operator=(operator/(operator+(a,b), b))
Scott Meyers, Software Development Consultant Kalb for NVIDIA Copyrighted material, all rights reserved.
http://www.aristeia.com/ http://cpp.training/ Slide 75
Scott Meyers, Software Development Consultant Kalb for NVIDIA Copyrighted material,
http://www.aristeia.com/ http://cpp.training/ all rights reserved.
Topics From Effective C++ Programming
Rvalue semantics
Will this compile?:
struct UPInt { ... }; // as before
UPInt operator+(UPInt const& lhs, UPInt const& rhs); // as before
UPInt operator/(UPInt const& lhs, UPInt const& rhs); // as before
UPInt a, b, c;
...
a + b = c;
Yes. It is the same as operator+(a, b).operator=(c).
Do we want it to compile?
Scott Meyers, Software Development Consultant Kalb for NVIDIA Copyrighted material, all rights reserved.
http://www.aristeia.com/ http://cpp.training/ Slide 76
Return-By-const-Value
Return-by-const-value can be useful:
§ This is a way to make objects act like rvalues for fundament types
Scott Meyers, Software Development Consultant Kalb for NVIDIA Copyrighted material, all rights reserved.
http://www.aristeia.com/ http://cpp.training/ Slide 77
Scott Meyers, Software Development Consultant Kalb for NVIDIA Copyrighted material,
http://www.aristeia.com/ http://cpp.training/ all rights reserved.
Topics From Effective C++ Programming
Return-By-const-Value
Any changes made to the value of a temporary, will be lost at the end of the
expression, when the temporary is destroyed.
Modifying a temporary is suspect because the changes are going to be lost
and the time/work to make them are wasted.
Is there any time that we’d want to modify a temporary?
What data is held by the UPInt class?
It may be that we’d like to take the allocated array of bits from a temporary
UPInt rather than allocating a new array and copying the bits. This is
possible in Modern C++ and we call it Move Semantics.
Guideline
§ Return const objects when you want to emulate rvalue semantics, but
not if you want to enable move operations.
§ If the type has resources that can be moved, we want to enable move
operations.
Scott Meyers, Software Development Consultant Kalb for NVIDIA Copyrighted material,
http://www.aristeia.com/ http://cpp.training/ all rights reserved.
Topics From Effective C++ Programming
Scott Meyers, Software Development Consultant Kalb for NVIDIA Copyrighted material, all rights reserved.
http://www.aristeia.com/ http://cpp.training/ Slide 80
Scott Meyers, Software Development Consultant Kalb for NVIDIA Copyrighted material,
http://www.aristeia.com/ http://cpp.training/ all rights reserved.
Topics From Effective C++ Programming
Overloading on const
Member functions differing only in their constness can be overloaded:
struct String {
...
char& operator[ ](int position)
{ return data[position]; }
char const& operator[ ](int position) const
{ return data[position]; }
private:
char *data;
};
String s1{"Hello"};
std::cout << s1[0]; // calls non-const String::operator[ ]
String const s2{"World"};
std::cout << s2[0]; // calls const String::operator[ ]
Scott Meyers, Software Development Consultant Kalb for NVIDIA Copyrighted material, all rights reserved.
http://www.aristeia.com/ http://cpp.training/ Slide 83
Scott Meyers, Software Development Consultant Kalb for NVIDIA Copyrighted material,
http://www.aristeia.com/ http://cpp.training/ all rights reserved.
Topics From Effective C++ Programming
Overloading on const
This lets you treat const and non-const objects differently:
String str{"World"}; // non-const String object
String const constStr{"Hello"}; // const String object
char c1{str[0]}; // fine — reading a
// non-const String
char c2{constStr[0]}; // fine — reading a
// const String
str[0] = 'x'; // fine — writing a
// non-const String
constStr[0] = 'x'; // error! — writing a
// const String
These differences in behavior would not occur if the two functions had the
same return type:
§ The use of const is crucial here, too
Scott Meyers, Software Development Consultant Kalb for NVIDIA Copyrighted material, all rights reserved.
http://www.aristeia.com/ http://cpp.training/ Slide 84
Scott Meyers, Software Development Consultant Kalb for NVIDIA Copyrighted material, all rights reserved.
http://www.aristeia.com/ http://cpp.training/ Slide 85
Scott Meyers, Software Development Consultant Kalb for NVIDIA Copyrighted material,
http://www.aristeia.com/ http://cpp.training/ all rights reserved.
Topics From Effective C++ Programming
Scott Meyers, Software Development Consultant Kalb for NVIDIA Copyrighted material, all rights reserved.
http://www.aristeia.com/ http://cpp.training/ Slide 86
Scott Meyers, Software Development Consultant Kalb for NVIDIA Copyrighted material, all rights reserved.
http://www.aristeia.com/ http://cpp.training/ Slide 87
Scott Meyers, Software Development Consultant Kalb for NVIDIA Copyrighted material,
http://www.aristeia.com/ http://cpp.training/ all rights reserved.
Topics From Effective C++ Programming
Scott Meyers, Software Development Consultant Kalb for NVIDIA Copyrighted material, all rights reserved.
http://www.aristeia.com/ http://cpp.training/ Slide 88
Enter mutable
Data members declared mutable may always be modified:
§ Even if inside a const member function or const object.
Implementing conceptual constness is thus straightforward:
§ Conceptually const member functions are declared const.
§ Data members that may need to change inside const member functions
are declared mutable.
Classes should be designed and implemented with support for conceptual
constness.
Scott Meyers, Software Development Consultant Kalb for NVIDIA Copyrighted material, all rights reserved.
http://www.aristeia.com/ http://cpp.training/ Slide 89
Scott Meyers, Software Development Consultant Kalb for NVIDIA Copyrighted material,
http://www.aristeia.com/ http://cpp.training/ all rights reserved.
Topics From Effective C++ Programming
Using mutable
struct String {
String(char const*value = 0)
: lengthIsValid{false} { ... }
std::size_t length() const;
...
private:
char *data;
mutable std::size_t dataLength; // last calculated length of string
Scott Meyers, Software Development Consultant Kalb for NVIDIA Copyrighted material, all rights reserved.
http://www.aristeia.com/ http://cpp.training/ Slide 90
Using mutable
This is now legal:
std::size_t String::length() const
{
if (!lengthIsValid) {
dataLength = std::strlen(data); // now okay
lengthIsValid = true; // now okay
}
return dataLength;
}
Scott Meyers, Software Development Consultant Kalb for NVIDIA Copyrighted material, all rights reserved.
http://www.aristeia.com/ http://cpp.training/ Slide 91
Scott Meyers, Software Development Consultant Kalb for NVIDIA Copyrighted material,
http://www.aristeia.com/ http://cpp.training/ all rights reserved.
Topics From Effective C++ Programming
Scott Meyers, Software Development Consultant Kalb for NVIDIA Copyrighted material, all rights reserved.
http://www.aristeia.com/ http://cpp.training/ Slide 92
Scott Meyers, Software Development Consultant Kalb for NVIDIA Copyrighted material, all rights reserved.
http://www.aristeia.com/ http://cpp.training/ Slide 93
Scott Meyers, Software Development Consultant Kalb for NVIDIA Copyrighted material,
http://www.aristeia.com/ http://cpp.training/ all rights reserved.
Topics From Effective C++ Programming
Scott Meyers, Software Development Consultant Kalb for NVIDIA Copyrighted material, all rights reserved.
http://www.aristeia.com/ http://cpp.training/ Slide 94
mutable
Disables bitwise const checking for “hidden” data members.
§ Common for caches:
struct Widget {
Scott Meyers, Software Development Consultant Kalb for NVIDIA Copyrighted material, all rights reserved.
http://www.aristeia.com/ http://cpp.training/ Slide 95
Scott Meyers, Software Development Consultant Kalb for NVIDIA Copyrighted material,
http://www.aristeia.com/ http://cpp.training/ all rights reserved.
Topics From Effective C++ Programming
Scott Meyers, Software Development Consultant Kalb for NVIDIA Copyrighted material, all rights reserved.
http://www.aristeia.com/ http://cpp.training/ Slide 96
Scott Meyers, Software Development Consultant Kalb for NVIDIA Copyrighted material, all rights reserved.
http://www.aristeia.com/ http://cpp.training/ Slide 97
Scott Meyers, Software Development Consultant Kalb for NVIDIA Copyrighted material,
http://www.aristeia.com/ http://cpp.training/ all rights reserved.
Topics From Effective C++ Programming
Scott Meyers, Software Development Consultant Kalb for NVIDIA Copyrighted material, all rights reserved.
http://www.aristeia.com/ http://cpp.training/ Slide 98
Revised Code
struct Widget {
Scott Meyers, Software Development Consultant Kalb for NVIDIA Copyrighted material, all rights reserved.
http://www.aristeia.com/ http://cpp.training/ Slide 99
Scott Meyers, Software Development Consultant Kalb for NVIDIA Copyrighted material,
http://www.aristeia.com/ http://cpp.training/ all rights reserved.
Topics From Effective C++ Programming
…
int getWeight() const
{
++callCount; // thread-safe RMW op.
return wt;
}
private:
mutable std::atomic<unsigned> callCount;
int wt;
};
Scott Meyers, Software Development Consultant Kalb for NVIDIA Copyrighted material, all rights reserved.
http://www.aristeia.com/ http://cpp.training/ Slide 100
Scott Meyers, Software Development Consultant Kalb for NVIDIA Copyrighted material, all rights reserved.
http://www.aristeia.com/ http://cpp.training/ Slide 101
Scott Meyers, Software Development Consultant Kalb for NVIDIA Copyrighted material,
http://www.aristeia.com/ http://cpp.training/ all rights reserved.
Topics From Effective C++ Programming
Scott Meyers, Software Development Consultant Kalb for NVIDIA Copyrighted material, all rights reserved.
http://www.aristeia.com/ http://cpp.training/ Slide 102
Scott Meyers, Software Development Consultant Kalb for NVIDIA Copyrighted material,
http://www.aristeia.com/ http://cpp.training/ all rights reserved.
Topics From Effective C++ Programming
Meaning of “Thread-Safe”
const member functions should be:
§ Bitwise const or
§ Internally synchronized.
Æ Typically via atomic data or mutex.
Scott Meyers, Software Development Consultant Kalb for NVIDIA Copyrighted material, all rights reserved.
http://www.aristeia.com/ http://cpp.training/ Slide 104
Guideline
Make const member functions thread-safe.
Scott Meyers, Software Development Consultant Kalb for NVIDIA Copyrighted material,
http://www.aristeia.com/ http://cpp.training/ all rights reserved.
Topics From Effective C++ Programming
Scott Meyers, Software Development Consultant Kalb for NVIDIA Copyrighted material, all rights reserved.
http://www.aristeia.com/ http://cpp.training/ Slide 106
Scott Meyers, Software Development Consultant Kalb for NVIDIA Copyrighted material, all rights reserved.
http://www.aristeia.com/ http://cpp.training/ Slide 107
Scott Meyers, Software Development Consultant Kalb for NVIDIA Copyrighted material,
http://www.aristeia.com/ http://cpp.training/ all rights reserved.
Topics From Effective C++ Programming
Scott Meyers, Software Development Consultant Kalb for NVIDIA Copyrighted material, all rights reserved.
http://www.aristeia.com/ http://cpp.training/ Slide 108
Type Aliases
A type alias can be created with either the (classic) keyword typedef:
typedef Widget const* WCP;
or with the (modern) keyword using:
using WCP = Widget const*;
These are just different syntaxes to do exactly the same thing. The modern
approached is preferred because:
• The new syntax is more general:
• Supports templated aliases
• Better to be consistent than to use two different styles.
• The new syntax is easier to understand.
Scott Meyers, Software Development Consultant Kalb for NVIDIA Copyrighted material, all rights reserved.
http://www.aristeia.com/ http://cpp.training/ Slide 109
Scott Meyers, Software Development Consultant Kalb for NVIDIA Copyrighted material,
http://www.aristeia.com/ http://cpp.training/ all rights reserved.
Topics From Effective C++ Programming
Scott Meyers, Software Development Consultant Kalb for NVIDIA Copyrighted material, all rights reserved.
http://www.aristeia.com/ http://cpp.training/ Slide 110
Scott Meyers, Software Development Consultant Kalb for NVIDIA Copyrighted material, all rights reserved.
http://www.aristeia.com/ http://cpp.training/ Slide 111
Scott Meyers, Software Development Consultant Kalb for NVIDIA Copyrighted material,
http://www.aristeia.com/ http://cpp.training/ all rights reserved.
Topics From Effective C++ Programming
Scott Meyers, Software Development Consultant Kalb for NVIDIA Copyrighted material, all rights reserved.
http://www.aristeia.com/ http://cpp.training/ Slide 112
Scott Meyers, Software Development Consultant Kalb for NVIDIA Copyrighted material, all rights reserved.
http://www.aristeia.com/ http://cpp.training/ Slide 113
Scott Meyers, Software Development Consultant Kalb for NVIDIA Copyrighted material,
http://www.aristeia.com/ http://cpp.training/ all rights reserved.
Topics From Effective C++ Programming
Scott Meyers, Software Development Consultant Kalb for NVIDIA Copyrighted material, all rights reserved.
http://www.aristeia.com/ http://cpp.training/ Slide 114
Scott Meyers, Software Development Consultant Kalb for NVIDIA Copyrighted material, all rights reserved.
http://www.aristeia.com/ http://cpp.training/ Slide 115
Scott Meyers, Software Development Consultant Kalb for NVIDIA Copyrighted material,
http://www.aristeia.com/ http://cpp.training/ all rights reserved.
Topics From Effective C++ Programming
const Summary
§ Use const whenever possible.
§ Type conversions involving multiple levels of indirection may seem
counterintuitive.
Æ If compilers object to your code, they’re probably right.
Scott Meyers, Software Development Consultant Kalb for NVIDIA Copyrighted material, all rights reserved.
http://www.aristeia.com/ http://cpp.training/ Slide 116
Scott Meyers, Software Development Consultant Kalb for NVIDIA Copyrighted material, all rights reserved.
http://www.aristeia.com/ http://cpp.training/ Slide 117
Scott Meyers, Software Development Consultant Kalb for NVIDIA Copyrighted material,
http://www.aristeia.com/ http://cpp.training/ all rights reserved.
Topics From Effective C++ Programming
Scott Meyers, Software Development Consultant Kalb for NVIDIA Copyrighted material, all rights reserved.
http://www.aristeia.com/ http://cpp.training/ Slide 118
Scott Meyers, Software Development Consultant Kalb for NVIDIA Copyrighted material, all rights reserved.
http://www.aristeia.com/ http://cpp.training/ Slide 119
Scott Meyers, Software Development Consultant Kalb for NVIDIA Copyrighted material,
http://www.aristeia.com/ http://cpp.training/ all rights reserved.
Topics From Effective C++ Programming
Scott Meyers, Software Development Consultant Kalb for NVIDIA Copyrighted material, all rights reserved.
http://www.aristeia.com/ http://cpp.training/ Slide 120
short vals[ArraySize];
…
for (auto& v : vals) { v = -v; }
Scott Meyers, Software Development Consultant Kalb for NVIDIA Copyrighted material, all rights reserved.
http://www.aristeia.com/ http://cpp.training/ Slide 121
Scott Meyers, Software Development Consultant Kalb for NVIDIA Copyrighted material,
http://www.aristeia.com/ http://cpp.training/ all rights reserved.
Topics From Effective C++ Programming
Scott Meyers, Software Development Consultant Kalb for NVIDIA Copyrighted material, all rights reserved.
http://www.aristeia.com/ http://cpp.training/ Slide 122
Introduction to
Rvalue References and Move Semantics
Scott Meyers, Software Development Consultant Kalb for NVIDIA Copyrighted material, all rights reserved.
http://www.aristeia.com/ http://cpp.training/ Slide 123
Scott Meyers, Software Development Consultant Kalb for NVIDIA Copyrighted material,
http://www.aristeia.com/ http://cpp.training/ all rights reserved.
Topics From Effective C++ Programming
Retronym
What are these?
Retronym
Classic C++ had “references”:
§ Syntax is type&
§ Semantic is “alias”
Scott Meyers, Software Development Consultant Kalb for NVIDIA Copyrighted material,
http://www.aristeia.com/ http://cpp.training/ all rights reserved.
Topics From Effective C++ Programming
Scott Meyers, Software Development Consultant Kalb for NVIDIA Copyrighted material,
http://www.aristeia.com/ http://cpp.training/ all rights reserved.
Topics From Effective C++ Programming
Scott Meyers, Software Development Consultant Kalb for NVIDIA Copyrighted material,
http://www.aristeia.com/ http://cpp.training/ all rights reserved.
Topics From Effective C++ Programming
struct Widget {
Widget(Widget const&); // copy constructor
Widget(Widget&&); // move constructor
Widget& operator=(Widget const&rhs); // copy assignment
Widget& operator=(Widget&&rhs); // move assignment
Kalb for NVIDIA Copyrighted material, all rights reserved.
http://cpp.training/ Slide 130
If not overloaded:
§ lvalue reference only:
Æ compiler will allow rvalue objects to bind to lvalue references
w safe: no stealing from lvalue objects
w backwards compatible
§ rvalue reference only:
Æ compiler will not allow lvalue objects to bind to rvalue references
w compile-time error instead of allowing stealing from lvalue objects
Scott Meyers, Software Development Consultant Kalb for NVIDIA Copyrighted material,
http://www.aristeia.com/ http://cpp.training/ all rights reserved.
Topics From Effective C++ Programming
Lvalues as Rvalues
In “naturally occurring code” an lvalue will never bind to an rvalue
reference parameter and so will never be moved from.
This is safe and backwards compatible.
But it isn’t always what we want.
Sometimes we want to move from an lvalue object. For this we have
std::move().
Widget a{MakeWidget()};
Widget b{std::move(a)}; // move constructor; “a” treated like rvalue
Type fundamentals
Special member functions
Scott Meyers, Software Development Consultant Kalb for NVIDIA Copyrighted material, all rights reserved.
http://www.aristeia.com/ http://cpp.training/ Slide 133
Scott Meyers, Software Development Consultant Kalb for NVIDIA Copyrighted material,
http://www.aristeia.com/ http://cpp.training/ all rights reserved.
Topics From Effective C++ Programming
Scott Meyers, Software Development Consultant Kalb for NVIDIA Copyrighted material, all rights reserved.
http://www.aristeia.com/ http://cpp.training/ Slide 134
Scott Meyers, Software Development Consultant Kalb for NVIDIA Copyrighted material, all rights reserved.
http://www.aristeia.com/ http://cpp.training/ Slide 135
Scott Meyers, Software Development Consultant Kalb for NVIDIA Copyrighted material,
http://www.aristeia.com/ http://cpp.training/ all rights reserved.
Topics From Effective C++ Programming
Scott Meyers, Software Development Consultant Kalb for NVIDIA Copyrighted material, all rights reserved.
http://www.aristeia.com/ http://cpp.training/ Slide 136
Scott Meyers, Software Development Consultant Kalb for NVIDIA Copyrighted material, all rights reserved.
http://www.aristeia.com/ http://cpp.training/ Slide 137
Scott Meyers, Software Development Consultant Kalb for NVIDIA Copyrighted material,
http://www.aristeia.com/ http://cpp.training/ all rights reserved.
Topics From Effective C++ Programming
Scott Meyers, Software Development Consultant Kalb for NVIDIA © 2014 Scott Meyers, all rights reserved.
http://www.aristeia.com/ http://cpp.training/ Slide 138
Scott Meyers, Software Development Consultant Kalb for NVIDIA © 2014 Scott Meyers, all rights reserved.
http://www.aristeia.com/ http://cpp.training/ Slide 139
Scott Meyers, Software Development Consultant Kalb for NVIDIA Copyrighted material,
http://www.aristeia.com/ http://cpp.training/ all rights reserved.
Topics From Effective C++ Programming
Scott Meyers, Software Development Consultant Kalb for NVIDIA © 2014 Scott Meyers, all rights reserved.
http://www.aristeia.com/ http://cpp.training/ Slide 140
Scott Meyers, Software Development Consultant Kalb for NVIDIA © 2014 Scott Meyers, all rights reserved.
http://www.aristeia.com/ http://cpp.training/ Slide 141
Scott Meyers, Software Development Consultant Kalb for NVIDIA Copyrighted material,
http://www.aristeia.com/ http://cpp.training/ all rights reserved.
Topics From Effective C++ Programming
Scott Meyers, Software Development Consultant Kalb for NVIDIA © 2014 Scott Meyers, all rights reserved.
http://www.aristeia.com/ http://cpp.training/ Slide 142
Scott Meyers, Software Development Consultant Kalb for NVIDIA © 2014 Scott Meyers, all rights reserved.
http://www.aristeia.com/ http://cpp.training/ Slide 143
Scott Meyers, Software Development Consultant Kalb for NVIDIA Copyrighted material,
http://www.aristeia.com/ http://cpp.training/ all rights reserved.
Topics From Effective C++ Programming
Default Behavior
Default constructor:
inline Empty::Empty(){}
Destructor:
inline Empty::~Empty() noexcept {}
§ The function is nonvirtual unless:
Æ it’s in a derived class and
Æa base class’s destructor is virtual
§ The destructor is noexcept unless
Æa base class’s destructor is noexcept(false) or
Æa data member’s destructor is noexcept(false)
Scott Meyers, Software Development Consultant Kalb for NVIDIA Copyrighted material, all rights reserved.
http://www.aristeia.com/ http://cpp.training/ Slide 144
Scott Meyers, Software Development Consultant Kalb for NVIDIA Copyrighted material, all rights reserved.
http://www.aristeia.com/ http://cpp.training/ Slide 145
Scott Meyers, Software Development Consultant Kalb for NVIDIA Copyrighted material,
http://www.aristeia.com/ http://cpp.training/ all rights reserved.
Topics From Effective C++ Programming
Scott Meyers, Software Development Consultant Kalb for NVIDIA Copyrighted material, all rights reserved.
http://www.aristeia.com/ http://cpp.training/ Slide 146
An Example
struct NamedInt {
NamedInt(char const*name, int value);
NamedInt(std::string const& name, int value);
...
private:
std::string nameValue; // a data member of struct type
int intValue; // a data member of built-in type
};
Scott Meyers, Software Development Consultant Kalb for NVIDIA Copyrighted material, all rights reserved.
http://www.aristeia.com/ http://cpp.training/ Slide 147
Scott Meyers, Software Development Consultant Kalb for NVIDIA Copyrighted material,
http://www.aristeia.com/ http://cpp.training/ all rights reserved.
Topics From Effective C++ Programming
An Example
The compiler will not generate a default constructor for NamedInt.
§ A constructor already exists.
It will generate a copy constructor and copy assignment operator (if
needed).
Consider:
NamedInt i{"Smallest Prime Number", 2};
NamedInt j{i}; // calls copy constructor
§ j.nameValue will be initialized by calling the string copy constructor
§ j.intValue will be initialized by bitwise copy
NamedInt k{std:move(i)}; // calls move constructor
§ k.nameValue will be initialized by calling the string move constructor
§ k.intValue will be initialized by bitwise copy
Scott Meyers, Software Development Consultant Kalb for NVIDIA Copyrighted material, all rights reserved.
http://www.aristeia.com/ http://cpp.training/ Slide 148
Scott Meyers, Software Development Consultant Kalb for NVIDIA Copyrighted material, all rights reserved.
http://www.aristeia.com/ http://cpp.training/ Slide 149
Scott Meyers, Software Development Consultant Kalb for NVIDIA Copyrighted material,
http://www.aristeia.com/ http://cpp.training/ all rights reserved.
Topics From Effective C++ Programming
Scott Meyers, Software Development Consultant Kalb for NVIDIA Copyrighted material, all rights reserved.
http://www.aristeia.com/ http://cpp.training/ Slide 150
Scott Meyers, Software Development Consultant Kalb for NVIDIA Copyrighted material, all rights reserved.
http://www.aristeia.com/ http://cpp.training/ Slide 151
Scott Meyers, Software Development Consultant Kalb for NVIDIA Copyrighted material,
http://www.aristeia.com/ http://cpp.training/ all rights reserved.
Topics From Effective C++ Programming
Scott Meyers, Software Development Consultant Kalb for NVIDIA © 2014 Scott Meyers, all rights reserved.
http://www.aristeia.com/ http://cpp.training/ Slide 152
Scott Meyers, Software Development Consultant Kalb for NVIDIA © 2014 Scott Meyers, all rights reserved.
http://www.aristeia.com/ http://cpp.training/ Slide 153
Scott Meyers, Software Development Consultant Kalb for NVIDIA Copyrighted material,
http://www.aristeia.com/ http://cpp.training/ all rights reserved.
Topics From Effective C++ Programming
Scott Meyers, Software Development Consultant Kalb for NVIDIA © 2014 Scott Meyers, all rights reserved.
http://www.aristeia.com/ http://cpp.training/ Slide 154
Guideline
Know what functions C++ silently writes and calls.
Scott Meyers, Software Development Consultant Kalb for NVIDIA Copyrighted material, all rights reserved.
http://www.aristeia.com/ http://cpp.training/ Slide 155
Scott Meyers, Software Development Consultant Kalb for NVIDIA Copyrighted material,
http://www.aristeia.com/ http://cpp.training/ all rights reserved.
Topics From Effective C++ Programming
Scott Meyers, Software Development Consultant Kalb for NVIDIA Copyrighted material, all rights reserved.
http://www.aristeia.com/ http://cpp.training/ Slide 156
Disallowing Assignment
Assignment is not allowed for built-in arrays:
char string1[10];
char string2[10];
string1 = string2; // error!
Assume you want to maintain this restriction:
PascalArray<int> intArray1( /* arguments */ );
PascalArray<int> intArray2( /* arguments */ );
intArray1 = intArray2; // should be an error
§ Usually, if you don’t want to provide some functionality, you just don’t
declare the function
§ This won’t work for operator=, because C++ will generate the function
automatically
Scott Meyers, Software Development Consultant Kalb for NVIDIA Copyrighted material, all rights reserved.
http://www.aristeia.com/ http://cpp.training/ Slide 157
Scott Meyers, Software Development Consultant Kalb for NVIDIA Copyrighted material,
http://www.aristeia.com/ http://cpp.training/ all rights reserved.
Topics From Effective C++ Programming
Scott Meyers, Software Development Consultant Kalb for NVIDIA Copyrighted material, all rights reserved.
http://www.aristeia.com/ http://cpp.training/ Slide 158
delete Functions
The Classic C++ approach to disallowing functions worked, but was a “hack”
to work around a language limitation.
That limitation is addressed in Modern C++ with deleted functions.
deleted functions are the Modern C++ alternative to the Classic C++ approach
for disallowing special functions.
This techniques is more powerful and more general than the Classic C++
approach.
Scott Meyers, Software Development Consultant Kalb for NVIDIA Copyrighted material,
http://www.aristeia.com/ http://cpp.training/ all rights reserved.
Topics From Effective C++ Programming
delete Functions
deleted functions are “defined,” but can’t be used.
§ Most common application: prevent object copying:
struct Widget {
Widget(Widget const&) = delete; // declare and
Widget& operator=(Widget const&) = delete; // make uncallable
…
};
§ Note that Widget isn’t movable, either.
w Declaring copy operations suppresses implicit move operations!
w It works both ways:
struct Gadget {
Gadget(Gadget&&) = delete; // these also
Gadget& operator=(Gadget&&) = delete; // suppress copy
… // operations
};
Scott Meyers, Software Development Consultant Kalb for NVIDIA © 2014 Scott Meyers, all rights reserved.
http://www.aristeia.com/ http://cpp.training/ Slide 160
delete Functions
Not limited to member functions.
§ Another common application: control argument conversions.
Æ deleted functions are declared, hence participate in overload
resolution:
void f(void*); // f callable with any ptr type
void f(char const*) = delete; // f uncallable with char [const]*
auto p1(new std::list<int>); // p1 is of type std::list<int>*
extern char *p2;
…
f(p1); // fine, calls f(void*)
f(p2); // error! F(char const*) unavailable
f("Modern C++"); // error!
f(u"Modern C++"); // fine (char16_t* ≠ char*)
Scott Meyers, Software Development Consultant Kalb for NVIDIA © 2014 Scott Meyers, all rights reserved.
http://www.aristeia.com/ http://cpp.training/ Slide 161
Scott Meyers, Software Development Consultant Kalb for NVIDIA Copyrighted material,
http://www.aristeia.com/ http://cpp.training/ all rights reserved.
Topics From Effective C++ Programming
Guideline
Explicitly disallow use of implicitly generated member functions you don’t
want.
Scott Meyers, Software Development Consultant Kalb for NVIDIA Copyrighted material, all rights reserved.
http://www.aristeia.com/ http://cpp.training/ Slide 162
Scott Meyers, Software Development Consultant Kalb for NVIDIA Copyrighted material, all rights reserved.
http://www.aristeia.com/ http://cpp.training/ Slide 163
Scott Meyers, Software Development Consultant Kalb for NVIDIA Copyrighted material,
http://www.aristeia.com/ http://cpp.training/ all rights reserved.
Topics From Effective C++ Programming
Scott Meyers, Software Development Consultant Kalb for NVIDIA Copyrighted material, all rights reserved.
http://www.aristeia.com/ http://cpp.training/ Slide 164
Scott Meyers, Software Development Consultant Kalb for NVIDIA Copyrighted material, all rights reserved.
http://www.aristeia.com/ http://cpp.training/ Slide 165
Scott Meyers, Software Development Consultant Kalb for NVIDIA Copyrighted material,
http://www.aristeia.com/ http://cpp.training/ all rights reserved.
Topics From Effective C++ Programming
Guideline
List members in an initialization list in declaration order.
Scott Meyers, Software Development Consultant Kalb for NVIDIA Copyrighted material, all rights reserved.
http://www.aristeia.com/ http://cpp.training/ Slide 166
Scott Meyers, Software Development Consultant Kalb for NVIDIA Copyrighted material, all rights reserved.
http://www.aristeia.com/ http://cpp.training/ Slide 167
Scott Meyers, Software Development Consultant Kalb for NVIDIA Copyrighted material,
http://www.aristeia.com/ http://cpp.training/ all rights reserved.
Topics From Effective C++ Programming
Scott Meyers, Software Development Consultant Kalb for NVIDIA Copyrighted material, all rights reserved.
http://www.aristeia.com/ http://cpp.training/ Slide 168
An Incorrect operator=
Consider:
struct Bitmap { … };
struct Widget {
…
private:
Bitmap *pb; // ptr to a heap-allocated
}; // object
This looks reasonable:
Widget& Widget::operator=(Widget const& rhs) // unsafe operator= impl.
{
delete pb; // get rid of old bitmap
pb = new Bitmap{*rhs.pb}; // take copy of new bitmap
return *this;
}
Scott Meyers, Software Development Consultant Kalb for NVIDIA Copyrighted material, all rights reserved.
http://www.aristeia.com/ http://cpp.training/ Slide 169
Scott Meyers, Software Development Consultant Kalb for NVIDIA Copyrighted material,
http://www.aristeia.com/ http://cpp.training/ all rights reserved.
Topics From Effective C++ Programming
pb
*this
rhs
Scott Meyers, Software Development Consultant Kalb for NVIDIA Copyrighted material, all rights reserved.
http://www.aristeia.com/ http://cpp.training/ Slide 170
pb
*this
rhs
Scott Meyers, Software Development Consultant Kalb for NVIDIA Copyrighted material, all rights reserved.
http://www.aristeia.com/ http://cpp.training/ Slide 171
Scott Meyers, Software Development Consultant Kalb for NVIDIA Copyrighted material,
http://www.aristeia.com/ http://cpp.training/ all rights reserved.
Topics From Effective C++ Programming
Scott Meyers, Software Development Consultant Kalb for NVIDIA Copyrighted material, all rights reserved.
http://www.aristeia.com/ http://cpp.training/ Slide 172
Scott Meyers, Software Development Consultant Kalb for NVIDIA Copyrighted material, all rights reserved.
http://www.aristeia.com/ http://cpp.training/ Slide 173
Scott Meyers, Software Development Consultant Kalb for NVIDIA Copyrighted material,
http://www.aristeia.com/ http://cpp.training/ all rights reserved.
Topics From Effective C++ Programming
Scott Meyers, Software Development Consultant Kalb for NVIDIA Copyrighted material, all rights reserved.
http://www.aristeia.com/ http://cpp.training/ Slide 174
Using Copy-and-Swap
A general approach to self-assignment-safe and exception-safe operator= is
based on a non-throwing swap member function:
struct Widget {
…
void swap(Widget& rhs) noexcept; // swap *this’s and rhs’s data in a
}; // nonthrowing operation
§ Many classes offer swap, e.g., all STL containers.
Æ It’s a common convention.
operator= can then be implemented via “copy and swap”:
Widget& Widget::operator=(Widget const& rhs)
{
Widget temp{rhs}; // copy rhs to temp
swap(temp); // swap *this’s and temp’s data
return *this; // destroy temp (and *this’s old data)
}
Scott Meyers, Software Development Consultant Kalb for NVIDIA Copyrighted material, all rights reserved.
http://www.aristeia.com/ http://cpp.training/ Slide 175
Scott Meyers, Software Development Consultant Kalb for NVIDIA Copyrighted material,
http://www.aristeia.com/ http://cpp.training/ all rights reserved.
Topics From Effective C++ Programming
Using Copy-and-Swap
Copy-and-swap is nice, but it always makes a copy:
§ A careful non-copying implementation can sometimes be more
efficient.
§ But copy-and-swap is a recognizable idiom.
Æ That improves maintainability.
Æ It’s also usually easier to get right.
w And to keep right as the function is maintained.
Scott Meyers, Software Development Consultant Kalb for NVIDIA Copyrighted material, all rights reserved.
http://www.aristeia.com/ http://cpp.training/ Slide 176
Back to Aliasing
As noted before, aliasing can lead to unobvious assignment to self. But
operator= is not the only function that must worry about aliasing:
struct Base {
void mf1(Base& rb); // rb and *this could
// be the same
...
};
void f1(Base& rb1, Base& rb2); // rb1 and rb2 could
// be the same
struct Derived: Base {
void mf2(Base& rb); // rb and *this could
// be the same
...
};
int f2(Derived& rd, Base& rb); // rd and rb could be
// the same
Scott Meyers, Software Development Consultant Kalb for NVIDIA Copyrighted material, all rights reserved.
http://www.aristeia.com/ http://cpp.training/ Slide 177
Scott Meyers, Software Development Consultant Kalb for NVIDIA Copyrighted material,
http://www.aristeia.com/ http://cpp.training/ all rights reserved.
Topics From Effective C++ Programming
Guidelines
Handle assignment to self in operator=.
§ Writing exception-safe code often handles it automatically.
§ Aliasing may also arise in other situations.
Scott Meyers, Software Development Consultant Kalb for NVIDIA Copyrighted material, all rights reserved.
http://www.aristeia.com/ http://cpp.training/ Slide 178
Scott Meyers, Software Development Consultant Kalb for NVIDIA Copyrighted material, all rights reserved.
http://www.aristeia.com/ http://cpp.training/ Slide 179
Scott Meyers, Software Development Consultant Kalb for NVIDIA Copyrighted material,
http://www.aristeia.com/ http://cpp.training/ all rights reserved.
Topics From Effective C++ Programming
Scott Meyers, Software Development Consultant Kalb for NVIDIA Copyrighted material, all rights reserved.
http://www.aristeia.com/ http://cpp.training/ Slide 181
Scott Meyers, Software Development Consultant Kalb for NVIDIA Copyrighted material,
http://www.aristeia.com/ http://cpp.training/ all rights reserved.
Topics From Effective C++ Programming
Scott Meyers, Software Development Consultant Kalb for NVIDIA Copyrighted material, all rights reserved.
http://www.aristeia.com/ http://cpp.training/ Slide 183
Scott Meyers, Software Development Consultant Kalb for NVIDIA Copyrighted material,
http://www.aristeia.com/ http://cpp.training/ all rights reserved.
Topics From Effective C++ Programming
Scott Meyers, Software Development Consultant Kalb for NVIDIA Copyrighted material, all rights reserved.
http://www.aristeia.com/ http://cpp.training/ Slide 184
Scott Meyers, Software Development Consultant Kalb for NVIDIA Copyrighted material, all rights reserved.
http://www.aristeia.com/ http://cpp.training/ Slide 185
Scott Meyers, Software Development Consultant Kalb for NVIDIA Copyrighted material,
http://www.aristeia.com/ http://cpp.training/ all rights reserved.
Topics From Effective C++ Programming
Scott Meyers, Software Development Consultant Kalb for NVIDIA Copyrighted material, all rights reserved.
http://www.aristeia.com/ http://cpp.training/ Slide 186
Scott Meyers, Software Development Consultant Kalb for NVIDIA Copyrighted material, all rights reserved.
http://www.aristeia.com/ http://cpp.training/ Slide 187
Scott Meyers, Software Development Consultant Kalb for NVIDIA Copyrighted material,
http://www.aristeia.com/ http://cpp.training/ all rights reserved.
Topics From Effective C++ Programming
pb1 pb2
B B
=
D D
Scott Meyers, Software Development Consultant Kalb for NVIDIA Copyrighted material, all rights reserved.
http://www.aristeia.com/ http://cpp.training/ Slide 188
pb1 pb2
B B
=
D1 D2
Scott Meyers, Software Development Consultant Kalb for NVIDIA Copyrighted material,
http://www.aristeia.com/ http://cpp.training/ all rights reserved.
Topics From Effective C++ Programming
Scott Meyers, Software Development Consultant Kalb for NVIDIA Copyrighted material,
http://www.aristeia.com/ http://cpp.training/ all rights reserved.
Topics From Effective C++ Programming
Scott Meyers, Software Development Consultant Kalb for NVIDIA Copyrighted material,
http://www.aristeia.com/ http://cpp.training/ all rights reserved.
Topics From Effective C++ Programming
Base Class
Make every base class an abstract class by giving it at least one pure virtual
function.
Make its copy and move assignment operators protected.
Leaf Class
Make every leaf class an concrete class that cannot be derived from.
Override each pure virtual function—so it can be instantiated.
Declare the class final—so that it can’t be derived from.
Make its copy and move assignment operators public.
Scott Meyers, Software Development Consultant Kalb for NVIDIA Copyrighted material,
http://www.aristeia.com/ http://cpp.training/ all rights reserved.
Topics From Effective C++ Programming
Base Class
struct Animal // abstract base class
{
Animal() = default; // public ctors as needed
Animal(Animal&&) = default;
virtual ~Animal() = 0; // pure virtual
protected: // copy/move assign ops
Animal& operator=(Animal const&) = default; // implemented, but
Animal& operator=(Animal&&) = default; // protected
};
inline Animal::~Animal() = default; // dtor is pure, but an
// implementation is
// provided
Scott Meyers, Software Development Consultant Kalb for NVIDIA Copyrighted material,
http://www.aristeia.com/ http://cpp.training/ all rights reserved.
Topics From Effective C++ Programming
Guideline
Scott’s solution, intended to solve a nasty implementation detail, results in
a valuable design guideline.
Classes should be used as bases or concrete classes, not both.
Guidelines
Assign to all data members in operator=.
Invoke base class copy/move constructors from derived class copy/move
constructors.
Make non-leaf classes abstract and leaf classes final.
Scott Meyers, Software Development Consultant Kalb for NVIDIA Copyrighted material, all rights reserved.
http://www.aristeia.com/ http://cpp.training/ Slide 199
Scott Meyers, Software Development Consultant Kalb for NVIDIA Copyrighted material,
http://www.aristeia.com/ http://cpp.training/ all rights reserved.
Topics From Effective C++ Programming
Scott Meyers, Software Development Consultant Kalb for NVIDIA Copyrighted material, all rights reserved.
http://www.aristeia.com/ http://cpp.training/ Slide 200
Scott Meyers, Software Development Consultant Kalb for NVIDIA Copyrighted material, all rights reserved.
http://www.aristeia.com/ http://cpp.training/ Slide 201
Scott Meyers, Software Development Consultant Kalb for NVIDIA Copyrighted material,
http://www.aristeia.com/ http://cpp.training/ all rights reserved.
Topics From Effective C++ Programming
Move Operations
Not supported by all types:
§ All types created before 2011 and many types created since then.
Æ Exception: types w/ compiler-generated move functions.
w Classes w/o destructor/copy/move function declarations.
Scott Meyers, Software Development Consultant Kalb for NVIDIA Copyrighted material, all rights reserved.
http://www.aristeia.com/ http://cpp.training/ Slide 202
Move Operations
When supported, not always faster than copying:
§ Small std::strings using SSO.
Æ For small capacities, move ≡ copy.
w “Small” often 7 or 15 characters.
Scott Meyers, Software Development Consultant Kalb for NVIDIA Copyrighted material, all rights reserved.
http://www.aristeia.com/ http://cpp.training/ Slide 203
Scott Meyers, Software Development Consultant Kalb for NVIDIA Copyrighted material,
http://www.aristeia.com/ http://cpp.training/ all rights reserved.
Topics From Effective C++ Programming
Move Operations
Generally restricted to rvalues:
§ Copying lvalues generally requires copying. Lvalues
Æ Moving generally not permitted.
Æ Note that result of std::move is rvalue.
Scott Meyers, Software Development Consultant Kalb for NVIDIA Copyrighted material, all rights reserved.
http://www.aristeia.com/ http://cpp.training/ Slide 204
Move Operations
Not always used. Consider:
std::string const stringValue("This string has 29 characters");
struct Widget {
Widget(): s{stringValue} {}
… // copy/move operations
private:
std::string s;
};
std::vector<Widget> vw;
Widget w;
for (std::size_t i{0}; i < n; ++i) { // append n copies
vw.push_back(w); // of w to vw
}
Scott Meyers, Software Development Consultant Kalb for NVIDIA Copyrighted material, all rights reserved.
http://www.aristeia.com/ http://cpp.training/ Slide 205
Scott Meyers, Software Development Consultant Kalb for NVIDIA Copyrighted material,
http://www.aristeia.com/ http://cpp.training/ all rights reserved.
Topics From Effective C++ Programming
Performance of n push_backs
Scott Meyers, Software Development Consultant Kalb for NVIDIA Copyrighted material, all rights reserved.
http://www.aristeia.com/ http://cpp.training/ Slide 206
Scott Meyers, Software Development Consultant Kalb for NVIDIA Copyrighted material, all rights reserved.
http://www.aristeia.com/ http://cpp.training/ Slide 207
Scott Meyers, Software Development Consultant Kalb for NVIDIA Copyrighted material,
http://www.aristeia.com/ http://cpp.training/ all rights reserved.
Topics From Effective C++ Programming
Recap
Move semantics (i.e., using move ops instead of copy ops) no help if:
§ Copy source is lvalue.
§ Type offers no move support.
§ Move no cheaper than copying.
§ Move unusable (i.e., move ops not noexcept).
Scott Meyers, Software Development Consultant Kalb for NVIDIA Copyrighted material, all rights reserved.
http://www.aristeia.com/ http://cpp.training/ Slide 208
Assume…
If, for some expression, you know
§ Types involved support cheap move operations and
§ Expression uses move operations
assumptions unnecessary.
§ Expression employs cheap move operations.
Æ Move ops vs. copy ops part of overload resolution.
w No compiler discretion.
Don’t know information above?
§ Assume the worst.
Æ Typically true for template code.
Scott Meyers, Software Development Consultant Kalb for NVIDIA Copyrighted material, all rights reserved.
http://www.aristeia.com/ http://cpp.training/ Slide 209
Scott Meyers, Software Development Consultant Kalb for NVIDIA Copyrighted material,
http://www.aristeia.com/ http://cpp.training/ all rights reserved.
Topics From Effective C++ Programming
Guideline
Assume that move operations are not present, not cheap, and not used.
This is a lie.
A useful lie.
For many purposes, the truth (reference collapsing) simply confuses.
§ We’ll cover the truth later.
Scott Meyers, Software Development Consultant Kalb for NVIDIA Copyrighted material, all rights reserved.
http://www.aristeia.com/ http://cpp.training/ Slide 211
Scott Meyers, Software Development Consultant Kalb for NVIDIA Copyrighted material,
http://www.aristeia.com/ http://cpp.training/ all rights reserved.
Topics From Effective C++ Programming
Scott Meyers, Software Development Consultant Kalb for NVIDIA Copyrighted material, all rights reserved.
http://www.aristeia.com/ http://cpp.training/ Slide 212
§ Universal reference
Æ Rvalue reference or lvalue reference.
w Syntactically type&&, but semantically type& or type&&.
Æ Bindslvalues and rvalues, const and non-const—everything!
Æ May facilitate copies, may facilitate moves.
Æ Same as Forwarding Reference.
Newer Terminology!
Scott Meyers, Software Development Consultant Kalb for NVIDIA Copyrighted material, all rights reserved.
http://www.aristeia.com/ http://cpp.training/ Slide 213
Scott Meyers, Software Development Consultant Kalb for NVIDIA Copyrighted material,
http://www.aristeia.com/ http://cpp.training/ all rights reserved.
Topics From Effective C++ Programming
Shorthands
§ LRef = Lvalue reference
§ RRef = Rvalue reference
§ URef = Universal reference
Scott Meyers, Software Development Consultant Kalb for NVIDIA Copyrighted material, all rights reserved.
http://www.aristeia.com/ http://cpp.training/ Slide 214
In a Nutshell
URefs arise in two contexts:
§ Function template parameters:
template<class T>
void f(T&& param);
§ auto declarations:
auto&& var(…);
Scott Meyers, Software Development Consultant Kalb for NVIDIA Copyrighted material, all rights reserved.
http://www.aristeia.com/ http://cpp.training/ Slide 215
Scott Meyers, Software Development Consultant Kalb for NVIDIA Copyrighted material,
http://www.aristeia.com/ http://cpp.training/ all rights reserved.
Topics From Effective C++ Programming
In a Nutshell
Scott Meyers, Software Development Consultant Kalb for NVIDIA Copyrighted material, all rights reserved.
http://www.aristeia.com/ http://cpp.training/ Slide 216
In a Nutshell
URefs require initializers:
§ Initializer for URef is lvalue ⇒ URef becomes LRef.
§ Initializer for URef is rvalue ⇒ URef becomes RRef.
Scott Meyers, Software Development Consultant Kalb for NVIDIA Copyrighted material, all rights reserved.
http://www.aristeia.com/ http://cpp.training/ Slide 217
Scott Meyers, Software Development Consultant Kalb for NVIDIA Copyrighted material,
http://www.aristeia.com/ http://cpp.training/ all rights reserved.
Topics From Effective C++ Programming
Examples
template<class T>
void f(T&& param); // URef: proper syntax + deduced type
Widget w;
f(w); // w is lvalue URef becomes LRef;
// f(Widget&) instantiated
f(std::move(w)); // std::move yields rvalue
// URef becomes RRef;
// f(Widget&&) instantiated
f(Widget{}); // Widget{} yields rvalue
// URef becomes RRef;
// f(Widget&&) instantiated
Scott Meyers, Software Development Consultant Kalb for NVIDIA Copyrighted material, all rights reserved.
http://www.aristeia.com/ http://cpp.training/ Slide 218
Examples
std::vector<int> v;
…
auto&& val(10); // 10 is rvalue URef becomes RRef;
// val’s type is int&&
auto&& element(v[5]): // v[5] returns int& and
// LRefs are lvalues
// v[5] is lvalue
// URef becomes LRef;
// element’s type is int&
Scott Meyers, Software Development Consultant Kalb for NVIDIA Copyrighted material, all rights reserved.
http://www.aristeia.com/ http://cpp.training/ Slide 219
Scott Meyers, Software Development Consultant Kalb for NVIDIA Copyrighted material,
http://www.aristeia.com/ http://cpp.training/ all rights reserved.
Topics From Effective C++ Programming
auto&&?
Uncommon in user code, but the basis of range-based for. Per C++11’s §6.5.4,
for ( for-range-declaration : expression ) statement
equivalent to
{
auto && __range = range-init;
for ( auto __begin(begin-expr), __end(end-expr);
__begin != __end;
++__begin ) {
for-range-declaration = *__begin;
statement
}
}
Scott Meyers, Software Development Consultant Kalb for NVIDIA Copyrighted material, all rights reserved.
http://www.aristeia.com/ http://cpp.training/ Slide 220
Scott Meyers, Software Development Consultant Kalb for NVIDIA Copyrighted material, all rights reserved.
http://www.aristeia.com/ http://cpp.training/ Slide 221
Scott Meyers, Software Development Consultant Kalb for NVIDIA Copyrighted material,
http://www.aristeia.com/ http://cpp.training/ all rights reserved.
Topics From Effective C++ Programming
std::vector<int> vi;
…
vi.push_back(10.5); // arg type is double, but
// parameter type is int&&
Scott Meyers, Software Development Consultant Kalb for NVIDIA Copyrighted material, all rights reserved.
http://www.aristeia.com/ http://cpp.training/ Slide 222
std::vector<int> vi;
…
vi.emplace_back(10.5); // arg type is double,
// parameter type is double&&
Scott Meyers, Software Development Consultant Kalb for NVIDIA Copyrighted material, all rights reserved.
http://www.aristeia.com/ http://cpp.training/ Slide 223
Scott Meyers, Software Development Consultant Kalb for NVIDIA Copyrighted material,
http://www.aristeia.com/ http://cpp.training/ all rights reserved.
Topics From Effective C++ Programming
Scott Meyers, Software Development Consultant Kalb for NVIDIA Copyrighted material, all rights reserved.
http://www.aristeia.com/ http://cpp.training/ Slide 224
Syntax Matters
URefs must have form type&& where type is entirely deduced.
template<class T>
void f(T&& param); // URef
template<class T>
void f(T const&& param); // RRef (const not deduced)
template<class T>
void f(std::vector<T>&& param); // RRef (std::vector not
// deduced)
Widget w;
auto&& v1(w); // URef LRef
auto const&& v2(w); // RRef; won’t compile
Scott Meyers, Software Development Consultant Kalb for NVIDIA Copyrighted material, all rights reserved.
http://www.aristeia.com/ http://cpp.training/ Slide 225
Scott Meyers, Software Development Consultant Kalb for NVIDIA Copyrighted material,
http://www.aristeia.com/ http://cpp.training/ all rights reserved.
Topics From Effective C++ Programming
Syntax Matters
Realm of artistic freedom:
§ Parameter name
§ White space :-)
template<class ParamType>
void f(ParamType&& param); // URef
template<class ParamType>
void f(ParamType && param); // URef
auto &&I_did_it_my_way(44); // URef
Scott Meyers, Software Development Consultant Kalb for NVIDIA Copyrighted material, all rights reserved.
http://www.aristeia.com/ http://cpp.training/ Slide 226
Guideline
Distinguish universal references from rvalue references.
Scott Meyers, Software Development Consultant Kalb for NVIDIA Copyrighted material,
http://www.aristeia.com/ http://cpp.training/ all rights reserved.
Topics From Effective C++ Programming
Scott Meyers, Software Development Consultant Kalb for NVIDIA Copyrighted material, all rights reserved.
http://www.aristeia.com/ http://cpp.training/ Slide 228
Scott Meyers, Software Development Consultant Kalb for NVIDIA Copyrighted material, all rights reserved.
http://www.aristeia.com/ http://cpp.training/ Slide 229
Scott Meyers, Software Development Consultant Kalb for NVIDIA Copyrighted material,
http://www.aristeia.com/ http://cpp.training/ all rights reserved.
Topics From Effective C++ Programming
Scott Meyers, Software Development Consultant Kalb for NVIDIA Copyrighted material, all rights reserved.
http://www.aristeia.com/ http://cpp.training/ Slide 230
Scott Meyers, Software Development Consultant Kalb for NVIDIA Copyrighted material, all rights reserved.
http://www.aristeia.com/ http://cpp.training/ Slide 231
Scott Meyers, Software Development Consultant Kalb for NVIDIA Copyrighted material,
http://www.aristeia.com/ http://cpp.training/ all rights reserved.
Topics From Effective C++ Programming
Scott Meyers, Software Development Consultant Kalb for NVIDIA Copyrighted material, all rights reserved.
http://www.aristeia.com/ http://cpp.training/ Slide 232
Scott Meyers, Software Development Consultant Kalb for NVIDIA Copyrighted material, all rights reserved.
http://www.aristeia.com/ http://cpp.training/ Slide 233
Scott Meyers, Software Development Consultant Kalb for NVIDIA Copyrighted material,
http://www.aristeia.com/ http://cpp.training/ all rights reserved.
Topics From Effective C++ Programming
std::move_if_noexcept
Replaces std::move when all following true:
§ C++98 code offers strong guarantee.
§ Replacing C++98 copy with C++11 move offers lesser guarantee.
Æ I.e., copy→move optimization reduces exception guarantee.
§ Knowing move won’t throw ⇒ strong guarantee possible.
Scott Meyers, Software Development Consultant Kalb for NVIDIA Copyrighted material, all rights reserved.
http://www.aristeia.com/ http://cpp.training/ Slide 234
Scott Meyers, Software Development Consultant Kalb for NVIDIA Copyrighted material, all rights reserved.
http://www.aristeia.com/ http://cpp.training/ Slide 235
Scott Meyers, Software Development Consultant Kalb for NVIDIA Copyrighted material,
http://www.aristeia.com/ http://cpp.training/ all rights reserved.
Topics From Effective C++ Programming
Scott Meyers, Software Development Consultant Kalb for NVIDIA Copyrighted material, all rights reserved.
http://www.aristeia.com/ http://cpp.training/ Slide 236
Scott Meyers, Software Development Consultant Kalb for NVIDIA Copyrighted material, all rights reserved.
http://www.aristeia.com/ http://cpp.training/ Slide 237
Scott Meyers, Software Development Consultant Kalb for NVIDIA Copyrighted material,
http://www.aristeia.com/ http://cpp.training/ all rights reserved.
Topics From Effective C++ Programming
Scott Meyers, Software Development Consultant Kalb for NVIDIA Copyrighted material, all rights reserved.
http://www.aristeia.com/ http://cpp.training/ Slide 238
Scott Meyers, Software Development Consultant Kalb for NVIDIA Copyrighted material, all rights reserved.
http://www.aristeia.com/ http://cpp.training/ Slide 239
Scott Meyers, Software Development Consultant Kalb for NVIDIA Copyrighted material,
http://www.aristeia.com/ http://cpp.training/ all rights reserved.
Topics From Effective C++ Programming
Scott Meyers, Software Development Consultant Kalb for NVIDIA Copyrighted material, all rights reserved.
http://www.aristeia.com/ http://cpp.training/ Slide 240
Copy Elision
The compiler is allowed to elide copies where results are “as if” copies were
made.
Return Value Optimization (commonly called RVO) is one such instance.
§ Caller allocates space on stack for return value, passes the address to callee
§ Callee constructs result directly in that space
Scott Meyers, Software Development Consultant Kalb for NVIDIA Copyrighted material,
http://www.aristeia.com/ http://cpp.training/ all rights reserved.
Topics From Effective C++ Programming
The function is passed the address where the results should be written.
243
Scott Meyers, Software Development Consultant Kalb for NVIDIA Copyrighted material,
http://www.aristeia.com/ http://cpp.training/ all rights reserved.
Topics From Effective C++ Programming
24
4
Scott Meyers, Software Development Consultant Kalb for NVIDIA Copyrighted material,
http://www.aristeia.com/ http://cpp.training/ all rights reserved.
Topics From Effective C++ Programming
temporaries •:"A"
• void g()
{
f(std::string{"A"});
locals y std::vector<int> y;
}
parameters g()
24
6
24
7
Scott Meyers, Software Development Consultant Kalb for NVIDIA Copyrighted material,
http://www.aristeia.com/ http://cpp.training/ all rights reserved.
Topics From Effective C++ Programming
Scott Meyers, Software Development Consultant Kalb for NVIDIA Copyrighted material, all rights reserved.
http://www.aristeia.com/ http://cpp.training/ Slide 248
Scott Meyers, Software Development Consultant Kalb for NVIDIA Copyrighted material, all rights reserved.
http://www.aristeia.com/ http://cpp.training/ Slide 249
Scott Meyers, Software Development Consultant Kalb for NVIDIA Copyrighted material,
http://www.aristeia.com/ http://cpp.training/ all rights reserved.
Topics From Effective C++ Programming
Scott Meyers, Software Development Consultant Kalb for NVIDIA Copyrighted material, all rights reserved.
http://www.aristeia.com/ http://cpp.training/ Slide 250
Return Types
All examples have shown by-value returns:
Widget f()
{
Widget w;
…
return w;
}
Matrix operator+(Matrix&& temp, Matrix const& y)
{
temp += y;
return std::move(temp);
}
Scott Meyers, Software Development Consultant Kalb for NVIDIA Copyrighted material, all rights reserved.
http://www.aristeia.com/ http://cpp.training/ Slide 251
Scott Meyers, Software Development Consultant Kalb for NVIDIA Copyrighted material,
http://www.aristeia.com/ http://cpp.training/ all rights reserved.
Topics From Effective C++ Programming
Scott Meyers, Software Development Consultant Kalb for NVIDIA Copyrighted material, all rights reserved.
http://www.aristeia.com/ http://cpp.training/ Slide 252
Scott Meyers, Software Development Consultant Kalb for NVIDIA Copyrighted material, all rights reserved.
http://www.aristeia.com/ http://cpp.training/ Slide 253
Scott Meyers, Software Development Consultant Kalb for NVIDIA Copyrighted material,
http://www.aristeia.com/ http://cpp.training/ all rights reserved.
Topics From Effective C++ Programming
Scott Meyers, Software Development Consultant Kalb for NVIDIA Copyrighted material, all rights reserved.
http://www.aristeia.com/ http://cpp.training/ Slide 254
Scott Meyers, Software Development Consultant Kalb for NVIDIA Copyrighted material, all rights reserved.
http://www.aristeia.com/ http://cpp.training/ Slide 255
Scott Meyers, Software Development Consultant Kalb for NVIDIA Copyrighted material,
http://www.aristeia.com/ http://cpp.training/ all rights reserved.
Topics From Effective C++ Programming
Guideline
Pass and return rvalue references via std::move, universal references via
std::forward.
Scott Meyers, Software Development Consultant Kalb for NVIDIA Copyrighted material, all rights reserved.
http://www.aristeia.com/ http://cpp.training/ Slide 257
Scott Meyers, Software Development Consultant Kalb for NVIDIA Copyrighted material,
http://www.aristeia.com/ http://cpp.training/ all rights reserved.
Topics From Effective C++ Programming
MessedUp m;
Widget w;
Widget const cw;
m.doWork(w); // doWork(T&&)
m.doWork(std::move(w)); // doWork(T&&)
m.doWork(cw); // doWork(T const&)
m.doWork(std::move(cw)); // doWork(T&&)
Scott Meyers, Software Development Consultant Kalb for NVIDIA Copyrighted material, all rights reserved.
http://www.aristeia.com/ http://cpp.training/ Slide 258
Scott Meyers, Software Development Consultant Kalb for NVIDIA Copyrighted material, all rights reserved.
http://www.aristeia.com/ http://cpp.training/ Slide 259
Scott Meyers, Software Development Consultant Kalb for NVIDIA Copyrighted material,
http://www.aristeia.com/ http://cpp.training/ all rights reserved.
Topics From Effective C++ Programming
Scott Meyers, Software Development Consultant Kalb for NVIDIA Copyrighted material, all rights reserved.
http://www.aristeia.com/ http://cpp.training/ Slide 260
Scott Meyers, Software Development Consultant Kalb for NVIDIA Copyrighted material, all rights reserved.
http://www.aristeia.com/ http://cpp.training/ Slide 261
Scott Meyers, Software Development Consultant Kalb for NVIDIA Copyrighted material,
http://www.aristeia.com/ http://cpp.training/ all rights reserved.
Topics From Effective C++ Programming
Scott Meyers, Software Development Consultant Kalb for NVIDIA Copyrighted material, all rights reserved.
http://www.aristeia.com/ http://cpp.training/ Slide 262
Reining in URefs
Curbing greed possible, but not pretty:
struct Person {
template<class NameT, // disable
class = typename std::enable_if< // ctor
!std::is_integral<NameT>::value // for
>::type> // integral
Person(NameT&& n) // types
: name{std::forward<NameT>(n)} {}
Person(int ID) // as
: name{nameFromID(ID)} {} // before
…
};
Scott Meyers, Software Development Consultant Kalb for NVIDIA Copyrighted material, all rights reserved.
http://www.aristeia.com/ http://cpp.training/ Slide 263
Scott Meyers, Software Development Consultant Kalb for NVIDIA Copyrighted material,
http://www.aristeia.com/ http://cpp.training/ all rights reserved.
Topics From Effective C++ Programming
Scott Meyers, Software Development Consultant Kalb for NVIDIA Copyrighted material, all rights reserved.
http://www.aristeia.com/ http://cpp.training/ Slide 264
URefs, Overloading,
and Special Member Functions
Consider class with “universal” copy/moving templates:
struct Widget {
…
template<class T>
Widget(T&&); // “universal” copy/move ctor
template<class T>
Widget& operator=(T&&); // “universal” copy/move op=
…
};
Seems to handle all argument types:
§ Lvalues + rvalues
§ const + non-const
§ volatile + non-volatile
Scott Meyers, Software Development Consultant Kalb for NVIDIA Copyrighted material, all rights reserved.
http://www.aristeia.com/ http://cpp.training/ Slide 265
Scott Meyers, Software Development Consultant Kalb for NVIDIA Copyrighted material,
http://www.aristeia.com/ http://cpp.training/ all rights reserved.
Topics From Effective C++ Programming
URefs, Overloading,
and Special Member Functions
Not that simple.
§ Overloading on URefs may be present.
Templates don’t suppress generation of special member functions.
§ Such functions generated overloading on URefs.
struct Widget {
…
template<class T>
Widget(T&&); // “universal” copy/move ctor
Widget(Widget const&); // generated copy ctor
Widget(Widget&&); // generated move ctor
template<class T>
Widget& operator=(T&&); // “universal” copy/move op=
Widget& operator=(Widget const&); // generated copy op=
Widget& operator=(Widget&&); // generated move op=
…
};
Scott Meyers, Software Development Consultant Kalb for NVIDIA Copyrighted material, all rights reserved.
http://www.aristeia.com/ http://cpp.training/ Slide 266
URefs, Overloading,
and Special Member Functions
Resulting behavior can again surprise:
struct Widget {
…
template<class T>
Widget(T&&); // “universal” copy/move ctor
Widget(Widget const&); // generated copy ctor
Widget(Widget&&); // generated move ctor
…
};
Widget w;
Widget const cw;
Widget copyLvalue{w}; // “universal” copy ctor
Widget copyRvalue{std::move(w)}; // generated move ctor
Widget copyConstLvalue{cw}; // generated copy ctor
Widget copyConstRvalue{std::move(cw)}; // “universal” move ctor
operator= behaves analogously.
Scott Meyers, Software Development Consultant Kalb for NVIDIA Copyrighted material, all rights reserved.
http://www.aristeia.com/ http://cpp.training/ Slide 267
Scott Meyers, Software Development Consultant Kalb for NVIDIA Copyrighted material,
http://www.aristeia.com/ http://cpp.training/ all rights reserved.
Topics From Effective C++ Programming
Widget w;
Widget const cw;
doWork(w); // doWork(T&&)
doWork(std::move(w)); // doWork(T&&)
doWork(cw); // doWork(T const&)
doWork(std::move(cw)); // doWork(T&&)
Scott Meyers, Software Development Consultant Kalb for NVIDIA Copyrighted material, all rights reserved.
http://www.aristeia.com/ http://cpp.training/ Slide 268
Scott Meyers, Software Development Consultant Kalb for NVIDIA Copyrighted material, all rights reserved.
http://www.aristeia.com/ http://cpp.training/ Slide 269
Scott Meyers, Software Development Consultant Kalb for NVIDIA Copyrighted material,
http://www.aristeia.com/ http://cpp.training/ all rights reserved.
Topics From Effective C++ Programming
Overloading Guideline
§ Overloading on RRef + LRef: typically OK.
§ Overloading on a URef: typically not OK.
Remember push_back versus emplace_back:
template<class T, class Allocator=allocator<T>>
struct vector {
…
void push_back(T const& x); // LRef (copy lvalues)
void push_back(T&& x); // RRef (move rvalues)
template<class... Args>
void emplace_back(Args&&... args); // URef (forward
… // everything)
};
Scott Meyers, Software Development Consultant Kalb for NVIDIA Copyrighted material, all rights reserved.
http://www.aristeia.com/ http://cpp.training/ Slide 270
Guideline
Avoid overloading on universal references.
Scott Meyers, Software Development Consultant Kalb for NVIDIA Copyrighted material,
http://www.aristeia.com/ http://cpp.training/ all rights reserved.
Topics From Effective C++ Programming
Scott Meyers, Software Development Consultant Kalb for NVIDIA Copyrighted material, all rights reserved.
http://www.aristeia.com/ http://cpp.training/ Slide 272
Scott Meyers, Software Development Consultant Kalb for NVIDIA Copyrighted material, all rights reserved.
http://www.aristeia.com/ http://cpp.training/ Slide 273
Scott Meyers, Software Development Consultant Kalb for NVIDIA Copyrighted material,
http://www.aristeia.com/ http://cpp.training/ all rights reserved.
Topics From Effective C++ Programming
Ref-To-Ref Generation
Lvalues thus yield a ref-to-ref:
template<class T> // as before
void f(T&& param);
Widget w;
f(w); // generates
// void f<Widget&>(Widget& && param);
Scott Meyers, Software Development Consultant Kalb for NVIDIA Copyrighted material, all rights reserved.
http://www.aristeia.com/ http://cpp.training/ Slide 274
Reference Collapsing
Generated refs-to-refs undergo reference collapsing:
§ T& & T&
§ T&& & T&
§ T& && T&
§ T&& && T&&
IOW,
§ RRef-to-RRef RRef
§ LRef-to-anything LRef
Æ Stephan T. Lavavej: “Lvalue references are infectious.”
Scott Meyers, Software Development Consultant Kalb for NVIDIA Copyrighted material, all rights reserved.
http://www.aristeia.com/ http://cpp.training/ Slide 275
Scott Meyers, Software Development Consultant Kalb for NVIDIA Copyrighted material,
http://www.aristeia.com/ http://cpp.training/ all rights reserved.
Topics From Effective C++ Programming
Scott Meyers, Software Development Consultant Kalb for NVIDIA Copyrighted material, all rights reserved.
http://www.aristeia.com/ http://cpp.training/ Slide 276
auto
Another ref-collapsing context.
§ Uses template type deduction rules (plus a bit more).
Widget w;
…
auto&& v1(w); // lvalue initializer
// auto&& → Widget& &&
// Widget&
auto&& v2(std::move(w)); // rvalue initializer
// auto&& → Widget&&
Scott Meyers, Software Development Consultant Kalb for NVIDIA Copyrighted material, all rights reserved.
http://www.aristeia.com/ http://cpp.training/ Slide 277
Scott Meyers, Software Development Consultant Kalb for NVIDIA Copyrighted material,
http://www.aristeia.com/ http://cpp.training/ all rights reserved.
Topics From Effective C++ Programming
Scott Meyers, Software Development Consultant Kalb for NVIDIA Copyrighted material, all rights reserved.
http://www.aristeia.com/ http://cpp.training/ Slide 278
decltype
decltype(expr) yields T& or T, and ref-collapsing applies.
§ Sounds like templates and auto.
§ Isn’t.
Æ Type evaluation rules are different:
w decltype(id) id’s declared type
w decltype(non-id lvalue expr) expr’s type; LRef (T&)
w decltype(non-id rvalue expr) expr’s type; non-ref (T)
Widget w;
decltype(w)&& r1{std::move(w)}; // r1’s type is Widget&&
decltype((w))&& r2{std::move(w)}; // r2’s type is Widget&
// (code won’t compile:
// initializer is rvalue)
Scott Meyers, Software Development Consultant Kalb for NVIDIA Copyrighted material, all rights reserved.
http://www.aristeia.com/ http://cpp.training/ Slide 279
Scott Meyers, Software Development Consultant Kalb for NVIDIA Copyrighted material,
http://www.aristeia.com/ http://cpp.training/ all rights reserved.
Topics From Effective C++ Programming
Scott Meyers, Software Development Consultant Kalb for NVIDIA Copyrighted material, all rights reserved.
http://www.aristeia.com/ http://cpp.training/ Slide 280
Scott Meyers, Software Development Consultant Kalb for NVIDIA Copyrighted material, all rights reserved.
http://www.aristeia.com/ http://cpp.training/ Slide 281
Scott Meyers, Software Development Consultant Kalb for NVIDIA Copyrighted material,
http://www.aristeia.com/ http://cpp.training/ all rights reserved.
Topics From Effective C++ Programming
Guideline
Understand reference collapsing.
Scott Meyers, Software Development Consultant Kalb for NVIDIA Copyrighted material, all rights reserved.
http://www.aristeia.com/ http://cpp.training/ Slide 284
Scott Meyers, Software Development Consultant Kalb for NVIDIA Copyrighted material,
http://www.aristeia.com/ http://cpp.training/ all rights reserved.
Topics From Effective C++ Programming
Perfect Forwarding
pft forwards to f whatever it gets.
§ Lvalue passed to pft ⇒ f gets the lvalue.
§ Ditto for rvalue.
§ Ditto for const and volatile.
Problem:
§ Lvalue/rvalue/const/volatile don’t cover everything.
Scott Meyers, Software Development Consultant Kalb for NVIDIA Copyrighted material, all rights reserved.
http://www.aristeia.com/ http://cpp.training/ Slide 285
Problem situations:
§ Argument type is “ambiguous.”
§ Argument type can’t be deduced.
§ Declaration-only argument not forwardable.
Scott Meyers, Software Development Consultant Kalb for NVIDIA Copyrighted material, all rights reserved.
http://www.aristeia.com/ http://cpp.training/ Slide 286
Scott Meyers, Software Development Consultant Kalb for NVIDIA Copyrighted material,
http://www.aristeia.com/ http://cpp.training/ all rights reserved.
Topics From Effective C++ Programming
Non-nullptr Nulls
To programmers, sometimes 0 ⇒ null, but to compilers, 0 ⇒ int:
void f(int*); // original function
template<class T> // forwarding template
void pft(T&& param)
{
…
f(std::forward<T>(param));
…
}
f(0); // fine
pft(0); // error! can’t pass int as int*
Scott Meyers, Software Development Consultant Kalb for NVIDIA Copyrighted material, all rights reserved.
http://www.aristeia.com/ http://cpp.training/ Slide 287
Non-nullptr Nulls
NULL doesn’t (portably) help:
f(NULL); // fine
pft(NULL); // error!
Scott Meyers, Software Development Consultant Kalb for NVIDIA Copyrighted material, all rights reserved.
http://www.aristeia.com/ http://cpp.training/ Slide 288
Scott Meyers, Software Development Consultant Kalb for NVIDIA Copyrighted material,
http://www.aristeia.com/ http://cpp.training/ all rights reserved.
Topics From Effective C++ Programming
nullptr
nullptr does:
void f(int*); // as before
template<class T> // as before
void pft(T&& param)
{
…
f(std::forward<T>(param));
…
}
f(nullptr); // fine
pft(nullptr); // also fine
Scott Meyers, Software Development Consultant Kalb for NVIDIA Copyrighted material, all rights reserved.
http://www.aristeia.com/ http://cpp.training/ Slide 289
Braced Initializers
Template type deduction fails for such initializers.
void f(std::string); // original function
template<class T> // forwarding template
void pft(T&& param)
{
…
f(std::forward<T>(param));
…
}
char c;
…
f({ '*', c, '*' }); // fine
pft({ '*', c, '*' }); // error! can’t deduce type for
// { '*', c, '*' }
Scott Meyers, Software Development Consultant Kalb for NVIDIA Copyrighted material, all rights reserved.
http://www.aristeia.com/ http://cpp.training/ Slide 290
Scott Meyers, Software Development Consultant Kalb for NVIDIA Copyrighted material,
http://www.aristeia.com/ http://cpp.training/ all rights reserved.
Topics From Effective C++ Programming
Braced Initializers
Interestingly, type deduction succeeds for auto:
§ Only difference between auto and template type deduction.
auto x = { '*', c, '*' }; // fine, x’s type is
// std::initializer_list<char>
Affords a workaround for callers:
f({ '*', c, '*' }); // still fine
pft({ '*', c, '*' }); // still an error
auto il = { '*', c, '*' };
pft(il); // fine
Scott Meyers, Software Development Consultant Kalb for NVIDIA Copyrighted material, all rights reserved.
http://www.aristeia.com/ http://cpp.training/ Slide 291
Braced Initializers
Workaround burden can be shifted to the interface.
§ Replace forwarding template w/forwarding functions:
void f(std::string); // as before
void fwd(std::string const& param) // forwarding function
{ // for lvalue strings
…
f(param);
…
}
void fwd(std::string&& param) // forwarding function
{ // for rvalue strings
…
f(std::move(param));
…
}
Scott Meyers, Software Development Consultant Kalb for NVIDIA Copyrighted material, all rights reserved.
http://www.aristeia.com/ http://cpp.training/ Slide 292
Scott Meyers, Software Development Consultant Kalb for NVIDIA Copyrighted material,
http://www.aristeia.com/ http://cpp.training/ all rights reserved.
Topics From Effective C++ Programming
Braced Initializers
Solves the problem:
f({ '*', c, '*' }); // fine
fwd({ '*', c, '*' }); // also fine
But can lead to unnecessary temporaries:
f("xyzzy"); // init f’s param via char const* ctor
fwd("xyzzy"); // bind fwd’s param to temporary
// std::string, then init f’s param
// with that
Scott Meyers, Software Development Consultant Kalb for NVIDIA Copyrighted material, all rights reserved.
http://www.aristeia.com/ http://cpp.training/ Slide 293
Braced Initializers
Function + template not perfect, but pretty good:
void fwd(std::string&& param) // #1: for non-const
{ // rvalue std::strings
…
f(std::move(param));
…
}
template<class T> // #2: for everything else
void fwd(T&& param)
{
…
f(std::forward<T>(param));
…
}
Scott Meyers, Software Development Consultant Kalb for NVIDIA Copyrighted material,
http://www.aristeia.com/ http://cpp.training/ all rights reserved.
Topics From Effective C++ Programming
Scott Meyers, Software Development Consultant Kalb for NVIDIA Copyrighted material, all rights reserved.
http://www.aristeia.com/ http://cpp.training/ Slide 295
Template Names
Templates lack types ⇒ can’t be deduced.
void f( void(int) ); // original function;
// ≡ “void f( void(*)(int) )”
template<class T> // forwarding template
void pft(T&& param)
{
…
f(std::forward<T>(param));
…
}
template<class T>
void funcTempl(T);
f(funcTempl); // fine, instantiates funcTempl<int>
pft(funcTempl); // error! can’t deduce type for funcTempl
Scott Meyers, Software Development Consultant Kalb for NVIDIA Copyrighted material, all rights reserved.
http://www.aristeia.com/ http://cpp.training/ Slide 296
Scott Meyers, Software Development Consultant Kalb for NVIDIA Copyrighted material,
http://www.aristeia.com/ http://cpp.training/ all rights reserved.
Topics From Effective C++ Programming
Template Names
Example is standard stream manipulators:
template <class charT, class traits> // from C++ Standards
basic_ostream<charT,traits>&
flush(basic_ostream<charT,traits>& os);
template<class T>
void print(T&& param)
{
…
std::cout << std::forward<T>(param);
…
}
std::cout << std::flush; // fine, same as
// operator<<(std::cout, std::flush);
// calls operator<<( ostream&(ostream&) )
print(std::flush); // error!
§ Ditto for std::endl, std::ends, std::ws
Scott Meyers, Software Development Consultant Kalb for NVIDIA Copyrighted material, all rights reserved.
http://www.aristeia.com/ http://cpp.training/ Slide 297
Scott Meyers, Software Development Consultant Kalb for NVIDIA Copyrighted material, all rights reserved.
http://www.aristeia.com/ http://cpp.training/ Slide 298
Scott Meyers, Software Development Consultant Kalb for NVIDIA Copyrighted material,
http://www.aristeia.com/ http://cpp.training/ all rights reserved.
Topics From Effective C++ Programming
IPv4Header h;
…
f(h.totalLength); // fine
pft(h.totalLength); // error!
Scott Meyers, Software Development Consultant Kalb for NVIDIA Copyrighted material, all rights reserved.
http://www.aristeia.com/ http://cpp.training/ Slide 299
Summary
Perfect forwarding failure cases:
§ 0 or NULL as null pointer.
§ Braced initializers.
§ Declaration-only integral const static members.
§ Template names.
§ Non-const lvalue bitfields
§ Others?
Scott Meyers, Software Development Consultant Kalb for NVIDIA Copyrighted material, all rights reserved.
http://www.aristeia.com/ http://cpp.training/ Slide 300
Scott Meyers, Software Development Consultant Kalb for NVIDIA Copyrighted material,
http://www.aristeia.com/ http://cpp.training/ all rights reserved.
Topics From Effective C++ Programming
Guideline
Familiarize yourself with perfect forwarding failure cases.
Scott Meyers, Software Development Consultant Kalb for NVIDIA Copyrighted material, all rights reserved.
http://www.aristeia.com/ http://cpp.training/ Slide 302
Scott Meyers, Software Development Consultant Kalb for NVIDIA Copyrighted material,
http://www.aristeia.com/ http://cpp.training/ all rights reserved.
Topics From Effective C++ Programming
STL
Algorithms
Containers
Scott Meyers, Software Development Consultant Kalb for NVIDIA Copyrighted material, all rights reserved.
http://www.aristeia.com/ http://cpp.training/ Slide 303
Scott Meyers, Software Development Consultant Kalb for NVIDIA Copyrighted material, all rights reserved.
http://www.aristeia.com/ http://cpp.training/ Slide 304
Scott Meyers, Software Development Consultant Kalb for NVIDIA Copyrighted material,
http://www.aristeia.com/ http://cpp.training/ all rights reserved.
Topics From Effective C++ Programming
p q
Scott Meyers, Software Development Consultant Kalb for NVIDIA Copyrighted material, all rights reserved.
http://www.aristeia.com/ http://cpp.training/ Slide 305
Searching an Array
Suppose we need a function to find the first occurrence of a value in an
array of ints.
Here’s one approach:
int* find(int *begin, int *end, int value)
{
while (begin != end && *begin != value) ++begin;
return begin;
}
§ We use the half-open range [begin, end) to specify the array to search.
§ We return a pointer to the first element containing value.
§ We detect the end of the range by checking to see if begin!=end.
Æ This generalizes better than checking to see if begin<end.
§ If value isn’t found, we return end.
Æ This generalizes better than NULL.
Æ To clients, end is as distinguishable as NULL, because it clearly points
outside the array.
Scott Meyers, Software Development Consultant Kalb for NVIDIA Copyrighted material, all rights reserved.
http://www.aristeia.com/ http://cpp.training/ Slide 306
Scott Meyers, Software Development Consultant Kalb for NVIDIA Copyrighted material,
http://www.aristeia.com/ http://cpp.training/ all rights reserved.
Topics From Effective C++ Programming
Using find
Search an entire array:
int values[50];
...
int *firstFive{find(values, values+50, 5)}; // search values for 5
if (firstFive != values+50) {
... // found it, firstFive points to it
}
else {
... // not found, *firstFive is
} // undefined
Search part of an array:
int n;
std::cin >> n;
int *firstn{find( values+10, // search for n in values[10]
values+20, // through values[19]
n)};
Scott Meyers, Software Development Consultant Kalb for NVIDIA Copyrighted material, all rights reserved.
http://www.aristeia.com/ http://cpp.training/ Slide 307
Generalizing find
Templatizing find allows it to work for arrays of any type:
template<class T>
T* find(T *begin, T *end, T const& value)
{
while (begin != end && *begin != value) ++begin;
return begin;
}
The original code still works:
int values[50];
...
int *firstFive{find(values, values+50, 5)}; // still works
find works with other types of arrays, too:
char letters[26];
...
char *firstA{find(letters, letters+26, 'A')}; // also works
Scott Meyers, Software Development Consultant Kalb for NVIDIA Copyrighted material, all rights reserved.
http://www.aristeia.com/ http://cpp.training/ Slide 308
Scott Meyers, Software Development Consultant Kalb for NVIDIA Copyrighted material,
http://www.aristeia.com/ http://cpp.training/ all rights reserved.
Topics From Effective C++ Programming
Scott Meyers, Software Development Consultant Kalb for NVIDIA Copyrighted material, all rights reserved.
http://www.aristeia.com/ http://cpp.training/ Slide 309
Scott Meyers, Software Development Consultant Kalb for NVIDIA Copyrighted material, all rights reserved.
http://www.aristeia.com/ http://cpp.training/ Slide 310
Scott Meyers, Software Development Consultant Kalb for NVIDIA Copyrighted material,
http://www.aristeia.com/ http://cpp.training/ all rights reserved.
Topics From Effective C++ Programming
Scott Meyers, Software Development Consultant Kalb for NVIDIA Copyrighted material, all rights reserved.
http://www.aristeia.com/ http://cpp.training/ Slide 311
std::find
find is part of the STL, but a standard-conforming implementation looks
slightly different:
template<class It, class T> // param order is reversed
It find(It begin, It end, T const& value)
{
while (begin != end &&
!(*begin == value)) // uses == instead of !=
++begin;
return begin;
}
These changes are insignificant to callers.
§ All examples we’ve seen continue to work with this implementation.
§ This implementation requires only that T support operator==, not
necessarily operator!=.
Æ Well-designed types support both if they support either.
Scott Meyers, Software Development Consultant Kalb for NVIDIA Copyrighted material, all rights reserved.
http://www.aristeia.com/ http://cpp.training/ Slide 312
Scott Meyers, Software Development Consultant Kalb for NVIDIA Copyrighted material,
http://www.aristeia.com/ http://cpp.training/ all rights reserved.
Topics From Effective C++ Programming
STL Algorithms
Function templates like find are known as algorithms.
§ Algorithms use iterators to specify half-open ranges defining the
sequences of values on which the algorithms should operate.
Scott Meyers, Software Development Consultant Kalb for NVIDIA Copyrighted material, all rights reserved.
http://www.aristeia.com/ http://cpp.training/ Slide 313
Scott Meyers, Software Development Consultant Kalb for NVIDIA Copyrighted material, all rights reserved.
http://www.aristeia.com/ http://cpp.training/ Slide 314
Scott Meyers, Software Development Consultant Kalb for NVIDIA Copyrighted material,
http://www.aristeia.com/ http://cpp.training/ all rights reserved.
Topics From Effective C++ Programming
Scott Meyers, Software Development Consultant Kalb for NVIDIA Copyrighted material, all rights reserved.
http://www.aristeia.com/ http://cpp.training/ Slide 315
Scott Meyers, Software Development Consultant Kalb for NVIDIA Copyrighted material, all rights reserved.
http://www.aristeia.com/ http://cpp.training/ Slide 316
Scott Meyers, Software Development Consultant Kalb for NVIDIA Copyrighted material,
http://www.aristeia.com/ http://cpp.training/ all rights reserved.
Topics From Effective C++ Programming
Scott Meyers, Software Development Consultant Kalb for NVIDIA Copyrighted material, all rights reserved.
http://www.aristeia.com/ http://cpp.training/ Slide 317
Scott Meyers, Software Development Consultant Kalb for NVIDIA Copyrighted material, all rights reserved.
http://www.aristeia.com/ http://cpp.training/ Slide 318
Scott Meyers, Software Development Consultant Kalb for NVIDIA Copyrighted material,
http://www.aristeia.com/ http://cpp.training/ all rights reserved.
Topics From Effective C++ Programming
Scott Meyers, Software Development Consultant Kalb for NVIDIA Copyrighted material, all rights reserved.
http://www.aristeia.com/ http://cpp.training/ Slide 319
Scott Meyers, Software Development Consultant Kalb for NVIDIA Copyrighted material, all rights reserved.
http://www.aristeia.com/ http://cpp.training/ Slide 320
Scott Meyers, Software Development Consultant Kalb for NVIDIA Copyrighted material,
http://www.aristeia.com/ http://cpp.training/ all rights reserved.
Topics From Effective C++ Programming
Scott Meyers, Software Development Consultant Kalb for NVIDIA Copyrighted material, all rights reserved.
http://www.aristeia.com/ http://cpp.training/ Slide 321
Scott Meyers, Software Development Consultant Kalb for NVIDIA Copyrighted material, all rights reserved.
http://www.aristeia.com/ http://cpp.training/ Slide 322
Scott Meyers, Software Development Consultant Kalb for NVIDIA Copyrighted material,
http://www.aristeia.com/ http://cpp.training/ all rights reserved.
Topics From Effective C++ Programming
Scott Meyers, Software Development Consultant Kalb for NVIDIA Copyrighted material, all rights reserved.
http://www.aristeia.com/ http://cpp.training/ Slide 323
Scott Meyers, Software Development Consultant Kalb for NVIDIA Copyrighted material, all rights reserved.
http://www.aristeia.com/ http://cpp.training/ Slide 324
Scott Meyers, Software Development Consultant Kalb for NVIDIA Copyrighted material,
http://www.aristeia.com/ http://cpp.training/ all rights reserved.
Topics From Effective C++ Programming
Scott Meyers, Software Development Consultant Kalb for NVIDIA Copyrighted material, all rights reserved.
http://www.aristeia.com/ http://cpp.training/ Slide 325
Scott Meyers, Software Development Consultant Kalb for NVIDIA Copyrighted material, all rights reserved.
http://www.aristeia.com/ http://cpp.training/ Slide 326
Scott Meyers, Software Development Consultant Kalb for NVIDIA Copyrighted material,
http://www.aristeia.com/ http://cpp.training/ all rights reserved.
Topics From Effective C++ Programming
Scott Meyers, Software Development Consultant Kalb for NVIDIA Copyrighted material, all rights reserved.
http://www.aristeia.com/ http://cpp.training/ Slide 327
Scott Meyers, Software Development Consultant Kalb for NVIDIA Copyrighted material, all rights reserved.
http://www.aristeia.com/ http://cpp.training/ Slide 328
Scott Meyers, Software Development Consultant Kalb for NVIDIA Copyrighted material,
http://www.aristeia.com/ http://cpp.training/ all rights reserved.
Topics From Effective C++ Programming
Scott Meyers, Software Development Consultant Kalb for NVIDIA Copyrighted material, all rights reserved.
http://www.aristeia.com/ http://cpp.training/ Slide 329
Using find_if
Our original find_if example continues to work:
bool equalsFive(int const& value) { return value == 5; }
int values[50];
...
int *firstFive{find_if(values, std::end(values), equalsFive)};
if (firstFive != std::end(values)) ...
The compiler figures out that It is int* and Pred is bool (*)(int const&).
§ Notice how the former type T (which was int) is now part of Pred.
Note that the std::begin() for an array is optional. The array name itself
decays into a pointer to the first element, which is what std::begin() returns.
Scott Meyers, Software Development Consultant Kalb for NVIDIA Copyrighted material, all rights reserved.
http://www.aristeia.com/ http://cpp.training/ Slide 330
Scott Meyers, Software Development Consultant Kalb for NVIDIA Copyrighted material,
http://www.aristeia.com/ http://cpp.training/ all rights reserved.
Topics From Effective C++ Programming
Using find_if
The vector example continues to work, too:
bool multipleOf5(int const& value) { return value % 5 == 0; }
std::vector<int> values;
...
auto firstMultiple(
find_if( begin(values), // find the first multiple of 5
end(values), // in the vector
multipleOf5));
if (firstMultiple != end(values)) ...
The compiler figures out that It is vector<int>::iterator and Pred is
bool(*)(const int&).
Scott Meyers, Software Development Consultant Kalb for NVIDIA Copyrighted material, all rights reserved.
http://www.aristeia.com/ http://cpp.training/ Slide 331
Using find_if
If we change multipleOf5 to use pass-by-value and to return an int, find_if
still works:
int multipleOf5(int value) { return value % 5 == 0 ? 1 : 0; }
std::vector<int> values;
...
auto firstMultiple(
find_if( begin(values), // find the first multiple of 5
end(values), // in the vector
multipleOf5));
if (firstMultiple != end(values)) ...
The compiler figures out that It is vector<int>::iterator and Pred is int (*)(int).
Inside find_if, multipleOf5’s int return type is implicitly converted to bool in
this statement:
while (begin != end && !p(*begin)) ... // p’s return type is implicitly
// converted to bool
Scott Meyers, Software Development Consultant Kalb for NVIDIA Copyrighted material, all rights reserved.
http://www.aristeia.com/ http://cpp.training/ Slide 332
Scott Meyers, Software Development Consultant Kalb for NVIDIA Copyrighted material,
http://www.aristeia.com/ http://cpp.training/ all rights reserved.
Topics From Effective C++ Programming
Function Objects
We can also use a function object as a predicate for find_if.
§ A function object is an object instantiated from a class declaring
operator() — the function call operator.
§ Function objects are also known as functors.
Æ Note: This a strictly C++ usage of the term. Functor has a completely
different meaning in the world of Functional Programming.
A class for checking if a value is within an epsilon of another value:
struct WithinEpsilon {
WithinEpsilon(double value, double epsilon)
: val{value}, ep{epsilon} {}
bool operator()(double x) const { return fabs(x-val) <= ep; }
private:
double val;
double ep;
};
Scott Meyers, Software Development Consultant Kalb for NVIDIA Copyrighted material, all rights reserved.
http://www.aristeia.com/ http://cpp.training/ Slide 333
Function Objects
It can be used with find_if like this:
WithinEpsilon checkVal{5.0, 0.3}; // checkVal returns true when it’s
// passed a value within 4.7-5.3
std::vector<float> values;
...
auto firstWithinEpsilon(
find_if( begin(values), // find the first element in values
end(values), // satisfying checkVal
checkVal));
if (firstWithinEpsilon != end(values)) ...
Here, the compiler figures out that It is vector<float>::iterator and Pred is
WithinEpsilon.
Consider this expression inside find_if:
while (begin != end && !p(*begin)) ... // 1. Convert *begin (which is
// float) to double
// 2. Invoke p.operator(),
// passing the double
Scott Meyers, Software Development Consultant Kalb for NVIDIA Copyrighted material, all rights reserved.
http://www.aristeia.com/ http://cpp.training/ Slide 334
Scott Meyers, Software Development Consultant Kalb for NVIDIA Copyrighted material,
http://www.aristeia.com/ http://cpp.training/ all rights reserved.
Topics From Effective C++ Programming
Function Objects
STL programmers rarely declare standalone function objects. Instead, they
create temporary function objects when they are needed:
std::vector<float> values;
...
auto firstWithinEpsilon( // again, find the first element
find_if( begin(values), // in the range 4.7-5.3
end(values),
WithinEpsilon{5.0, 0.3})); // create temporary
// WithinEpsilon object to
// pass to find_if
if (firstWithinEpsilon != end(values)) ...
Function Objects
Function object classes are nice, because they can generate lots of different
function objects:
...
auto pElem1( // find the first element
find_if( begin(values), // in the range -1.2 to 4.2
end(values),
WithinEpsilon{1.5, 2.7})); // create temporary
...
auto pElem2( // find the first element
find_if( begin(values), // in the range -0.1 to 0.1
end(values),
WithinEpsilon{0.0, 0.1})); // create temporary
Scott Meyers, Software Development Consultant Kalb for NVIDIA Copyrighted material, all rights reserved.
http://www.aristeia.com/ http://cpp.training/ Slide 336
Scott Meyers, Software Development Consultant Kalb for NVIDIA Copyrighted material,
http://www.aristeia.com/ http://cpp.training/ all rights reserved.
Topics From Effective C++ Programming
Function Objects
Templates can generate multiple functions, too, but each template
instantiation is a different function:
§ That can lead to code bloat (for non-inline functions).
Æ Only one copy of WithinEpsilon’s member functions will be
generated, no matter how many objects are created.
Function objects are also more flexible than templates:
§ Their behavior can be customized via constructor arguments and other
member function calls.
§ “Calls” (i.e., invocations of operator()) can be inlined.
Æ This is rarely done when function pointers are passed as parameters.
Lambda expression combine the performance (and inline-ability) of
function objects with a syntactic expressiveness not available in Classic
C++.
Scott Meyers, Software Development Consultant Kalb for NVIDIA Copyrighted material, all rights reserved.
http://www.aristeia.com/ http://cpp.training/ Slide 337
Scott Meyers, Software Development Consultant Kalb for NVIDIA Copyrighted material, all rights reserved.
http://www.aristeia.com/ http://cpp.training/ Slide 338
Scott Meyers, Software Development Consultant Kalb for NVIDIA Copyrighted material,
http://www.aristeia.com/ http://cpp.training/ all rights reserved.
Topics From Effective C++ Programming
Scott Meyers, Software Development Consultant Kalb for NVIDIA Copyrighted material, all rights reserved.
http://www.aristeia.com/ http://cpp.training/ Slide 339
Scott Meyers, Software Development Consultant Kalb for NVIDIA Copyrighted material, all rights reserved.
http://www.aristeia.com/ http://cpp.training/ Slide 340
Scott Meyers, Software Development Consultant Kalb for NVIDIA Copyrighted material,
http://www.aristeia.com/ http://cpp.training/ all rights reserved.
Topics From Effective C++ Programming
Scott Meyers, Software Development Consultant Kalb for NVIDIA Copyrighted material, all rights reserved.
http://www.aristeia.com/ http://cpp.training/ Slide 341
Scott Meyers, Software Development Consultant Kalb for NVIDIA Copyrighted material, all rights reserved.
http://www.aristeia.com/ http://cpp.training/ Slide 342
Scott Meyers, Software Development Consultant Kalb for NVIDIA Copyrighted material,
http://www.aristeia.com/ http://cpp.training/ all rights reserved.
Topics From Effective C++ Programming
deque
list
set
multiset
map
multimap
Scott Meyers, Software Development Consultant Kalb for NVIDIA Copyrighted material, all rights reserved.
Slide 343
http://www.aristeia.com/ http://cpp.training/
unordered_set
unordered_multiset
unordered_map
unordered_multimap
Scott Meyers, Software Development Consultant Kalb for NVIDIA Copyrighted material, all rights reserved.
http://www.aristeia.com/ http://cpp.training/ Slide 344
Scott Meyers, Software Development Consultant Kalb for NVIDIA Copyrighted material,
http://www.aristeia.com/ http://cpp.training/ all rights reserved.
Topics From Effective C++ Programming
Scott Meyers, Software Development Consultant Kalb for NVIDIA Copyrighted material, all rights reserved.
http://www.aristeia.com/ http://cpp.training/ Slide 345
Scott Meyers, Software Development Consultant Kalb for NVIDIA Copyrighted material, all rights reserved.
http://www.aristeia.com/ http://cpp.training/ Slide 346
Scott Meyers, Software Development Consultant Kalb for NVIDIA Copyrighted material,
http://www.aristeia.com/ http://cpp.training/ all rights reserved.
Topics From Effective C++ Programming
5 22 9 10 16 10 16 18 16
begin(v) end(v)
5 22 9 10 16 10 16 18 16
5 22 9 10 10 18 16 18 16
begin(v) newEnd end(v)
Scott Meyers, Software Development Consultant Kalb for NVIDIA Copyrighted material, all rights reserved.
http://www.aristeia.com/ http://cpp.training/ Slide 347
Scott Meyers, Software Development Consultant Kalb for NVIDIA Copyrighted material, all rights reserved.
http://www.aristeia.com/ http://cpp.training/ Slide 348
Scott Meyers, Software Development Consultant Kalb for NVIDIA Copyrighted material,
http://www.aristeia.com/ http://cpp.training/ all rights reserved.
Topics From Effective C++ Programming
5 22 9 10 10 18
begin(v) newEnd v.end(v)
Scott Meyers, Software Development Consultant Kalb for NVIDIA Copyrighted material, all rights reserved.
http://www.aristeia.com/ http://cpp.training/ Slide 350
Scott Meyers, Software Development Consultant Kalb for NVIDIA Copyrighted material,
http://www.aristeia.com/ http://cpp.training/ all rights reserved.
Topics From Effective C++ Programming
Guideline
Understand the behavior of remove.
Scott Meyers, Software Development Consultant Kalb for NVIDIA Copyrighted material, all rights reserved.
http://www.aristeia.com/ http://cpp.training/ Slide 351
Algorithms
Scott Meyers, Software Development Consultant Kalb for NVIDIA Copyrighted material, all rights reserved.
http://www.aristeia.com/ http://cpp.training/ Slide 352
Scott Meyers, Software Development Consultant Kalb for NVIDIA Copyrighted material,
http://www.aristeia.com/ http://cpp.training/ all rights reserved.
Topics From Effective C++ Programming
Scott Meyers, Software Development Consultant Kalb for NVIDIA Copyrighted material, all rights reserved.
http://www.aristeia.com/ http://cpp.training/ Slide 353
Scott Meyers, Software Development Consultant Kalb for NVIDIA Copyrighted material, all rights reserved.
http://www.aristeia.com/ http://cpp.training/ Slide 354
Scott Meyers, Software Development Consultant Kalb for NVIDIA Copyrighted material,
http://www.aristeia.com/ http://cpp.training/ all rights reserved.
Topics From Effective C++ Programming
nth_element
nth_element is remarkably useful:
§ Find the Widget with the median level of quality:
std::vector<Widget>::iterator begin(begin(widgets)); // convenience vars
std::vector<Widget>::iterator end(end(widgets)); // for widgets’ begin
// and end iterators
std::vector<Widget>::iterator goalPosition; // where the widget
// of interest is
goalPosition = begin + widgets.size() / 2; // the widget of interest
// would be in the middle
// of the sorted vector
std::nth_element( begin, goalPosition, end, // find the median quality
qualityCompare); // value in widgets
... // goalPosition now points
// to the Widget with a
// median level of quality
Scott Meyers, Software Development Consultant Kalb for NVIDIA Copyrighted material, all rights reserved.
http://www.aristeia.com/ http://cpp.training/ Slide 355
nth_element
§ Find the Widget with a level of quality at the 75th percentile:
std::vector<Widget>::size_type goalOffset{ // figure out how far
0.25 * widgets.size()}; // from the beginning
// the Widget of
// interest is
std::nth_element( begin, begin + goalOffset, end, // find quality value at
qualityCompare); // the 75th percentile
... // begin+goalOffset
// now points to the
// Widget at the 75th
// percentile level of
// quality
Scott Meyers, Software Development Consultant Kalb for NVIDIA Copyrighted material, all rights reserved.
http://www.aristeia.com/ http://cpp.training/ Slide 356
Scott Meyers, Software Development Consultant Kalb for NVIDIA Copyrighted material,
http://www.aristeia.com/ http://cpp.training/ all rights reserved.
Topics From Effective C++ Programming
Scott Meyers, Software Development Consultant Kalb for NVIDIA Copyrighted material, all rights reserved.
http://www.aristeia.com/ http://cpp.training/ Slide 357
Scott Meyers, Software Development Consultant Kalb for NVIDIA Copyrighted material, all rights reserved.
http://www.aristeia.com/ http://cpp.training/ Slide 358
Scott Meyers, Software Development Consultant Kalb for NVIDIA Copyrighted material,
http://www.aristeia.com/ http://cpp.training/ all rights reserved.
Topics From Effective C++ Programming
Stability
Suppose many Widgets have equivalent quality ratings. How do sort,
partial_sort, nth_element, and partition order them?
§ Any way they want to.
§ You can’t change this.
But sometimes you want stability:
§ A sort is stable if the relative positions of equivalent elements are
guaranteed to be preserved during the sort.
sort isn’t stable, but stable_sort is.
partition isn’t stable, but stable_partition is.
partial_sort and nth_element aren’t stable.
§ The STL offers no stable versions of these algorithms.
§ If you need stability, you probably want to use stable_sort.
Scott Meyers, Software Development Consultant Kalb for NVIDIA Copyrighted material, all rights reserved.
http://www.aristeia.com/ http://cpp.training/ Slide 359
Iterator Requirements
sort, stable_sort, partial_sort, nth_element require random access iterators:
§ Applicable to vectors, strings, deques, valarrays, and arrays.
list has a sort member function:
§ It performs a stable sort.
§ To apply the other sorting algorithms to a list, consider these options:
Æ Copy/move list data into a container with random access iterators,
sort that, copy/move the data back.
Æ Create a container of list::iterators, sort that, and access list elements
via the iterators.
Æ Create a container of list::iterators, sort that, then use it to iteratively
splice list elements into the desired order.
partition and stable_partition require only bidirectional iterators.
§ They may be applied to any standard sequence container.
It makes no sense to try to sort the standard associative containers.
Scott Meyers, Software Development Consultant Kalb for NVIDIA Copyrighted material, all rights reserved.
http://www.aristeia.com/ http://cpp.training/ Slide 360
Scott Meyers, Software Development Consultant Kalb for NVIDIA Copyrighted material,
http://www.aristeia.com/ http://cpp.training/ all rights reserved.
Topics From Effective C++ Programming
Scott Meyers, Software Development Consultant Kalb for NVIDIA Copyrighted material, all rights reserved.
http://www.aristeia.com/ http://cpp.training/ Slide 361
Scott Meyers, Software Development Consultant Kalb for NVIDIA Copyrighted material, all rights reserved.
http://www.aristeia.com/ http://cpp.training/ Slide 362
Scott Meyers, Software Development Consultant Kalb for NVIDIA Copyrighted material,
http://www.aristeia.com/ http://cpp.training/ all rights reserved.
Topics From Effective C++ Programming
Scott Meyers, Software Development Consultant Kalb for NVIDIA Copyrighted material, all rights reserved.
http://www.aristeia.com/ http://cpp.training/ Slide 363
Guideline
Know your sorting options.
Scott Meyers, Software Development Consultant Kalb for NVIDIA Copyrighted material, all rights reserved.
http://www.aristeia.com/ http://cpp.training/ Slide 364
Scott Meyers, Software Development Consultant Kalb for NVIDIA Copyrighted material,
http://www.aristeia.com/ http://cpp.training/ all rights reserved.
Topics From Effective C++ Programming
Scott Meyers, Software Development Consultant Kalb for NVIDIA Copyrighted material, all rights reserved.
http://www.aristeia.com/ http://cpp.training/ Slide 365
Scott Meyers, Software Development Consultant Kalb for NVIDIA Copyrighted material, all rights reserved.
http://www.aristeia.com/ http://cpp.training/ Slide 366
Scott Meyers, Software Development Consultant Kalb for NVIDIA Copyrighted material,
http://www.aristeia.com/ http://cpp.training/ all rights reserved.
Topics From Effective C++ Programming
The following algorithms work on unsorted ranges, but they’re most useful
when applied to sorted ranges:
unique unique_copy
§ They eliminate adjacent duplicates, so when ranges are sorted, they
eliminate all duplicates:
Æ They “eliminate” elements just like remove does.
Scott Meyers, Software Development Consultant Kalb for NVIDIA Copyrighted material, all rights reserved.
http://www.aristeia.com/ http://cpp.training/ Slide 367
Scott Meyers, Software Development Consultant Kalb for NVIDIA Copyrighted material, all rights reserved.
http://www.aristeia.com/ http://cpp.training/ Slide 368
Scott Meyers, Software Development Consultant Kalb for NVIDIA Copyrighted material,
http://www.aristeia.com/ http://cpp.training/ all rights reserved.
Topics From Effective C++ Programming
Scott Meyers, Software Development Consultant Kalb for NVIDIA Copyrighted material, all rights reserved.
http://www.aristeia.com/ http://cpp.training/ Slide 369
Guideline
Note which algorithms expect sorted ranges.
Scott Meyers, Software Development Consultant Kalb for NVIDIA Copyrighted material, all rights reserved.
http://www.aristeia.com/ http://cpp.training/ Slide 370
Scott Meyers, Software Development Consultant Kalb for NVIDIA Copyrighted material,
http://www.aristeia.com/ http://cpp.training/ all rights reserved.
Topics From Effective C++ Programming
Algorithms Summary
§ Know your sorting options.
§ Note which algorithms expect sorted ranges.
Scott Meyers, Software Development Consultant Kalb for NVIDIA Copyrighted material, all rights reserved.
http://www.aristeia.com/ http://cpp.training/ Slide 371
Containers
Scott Meyers, Software Development Consultant Kalb for NVIDIA Copyrighted material, all rights reserved.
http://www.aristeia.com/ http://cpp.training/ Slide 372
Scott Meyers, Software Development Consultant Kalb for NVIDIA Copyrighted material,
http://www.aristeia.com/ http://cpp.training/ all rights reserved.
Topics From Effective C++ Programming
Scott Meyers, Software Development Consultant Kalb for NVIDIA Copyrighted material, all rights reserved.
http://www.aristeia.com/ http://cpp.training/ Slide 373
Scott Meyers, Software Development Consultant Kalb for NVIDIA Copyrighted material, all rights reserved.
http://www.aristeia.com/ http://cpp.training/ Slide 374
Scott Meyers, Software Development Consultant Kalb for NVIDIA Copyrighted material,
http://www.aristeia.com/ http://cpp.training/ all rights reserved.
Topics From Effective C++ Programming
array
vector
string
deque
Æ So is rope.
Scott Meyers, Software Development Consultant Kalb for NVIDIA Copyrighted material, all rights reserved.
http://www.aristeia.com/ http://cpp.training/ Slide 375
Scott Meyers, Software Development Consultant Kalb for NVIDIA Copyrighted material, all rights reserved.
http://www.aristeia.com/ http://cpp.training/ Slide 376
Scott Meyers, Software Development Consultant Kalb for NVIDIA Copyrighted material,
http://www.aristeia.com/ http://cpp.training/ all rights reserved.
Topics From Effective C++ Programming
Scott Meyers, Software Development Consultant Kalb for NVIDIA Copyrighted material, all rights reserved.
http://www.aristeia.com/ http://cpp.training/ Slide 377
Scott Meyers, Software Development Consultant Kalb for NVIDIA Copyrighted material, all rights reserved.
http://www.aristeia.com/ http://cpp.training/ Slide 378
Scott Meyers, Software Development Consultant Kalb for NVIDIA Copyrighted material,
http://www.aristeia.com/ http://cpp.training/ all rights reserved.
Topics From Effective C++ Programming
Scott Meyers, Software Development Consultant Kalb for NVIDIA Copyrighted material, all rights reserved.
http://www.aristeia.com/ http://cpp.training/ Slide 379
Scott Meyers, Software Development Consultant Kalb for NVIDIA Copyrighted material, all rights reserved.
http://www.aristeia.com/ http://cpp.training/ Slide 380
Scott Meyers, Software Development Consultant Kalb for NVIDIA Copyrighted material,
http://www.aristeia.com/ http://cpp.training/ all rights reserved.
Topics From Effective C++ Programming
Guideline
Choose your containers with care.
Scott Meyers, Software Development Consultant Kalb for NVIDIA Copyrighted material, all rights reserved.
http://www.aristeia.com/ http://cpp.training/ Slide 381
Scott Meyers, Software Development Consultant Kalb for NVIDIA Copyrighted material, all rights reserved.
http://www.aristeia.com/ http://cpp.training/ Slide 382
Scott Meyers, Software Development Consultant Kalb for NVIDIA Copyrighted material,
http://www.aristeia.com/ http://cpp.training/ all rights reserved.
Topics From Effective C++ Programming
Scott Meyers, Software Development Consultant Kalb for NVIDIA Copyrighted material, all rights reserved.
http://www.aristeia.com/ http://cpp.training/ Slide 383
Scott Meyers, Software Development Consultant Kalb for NVIDIA Copyrighted material, all rights reserved.
http://www.aristeia.com/ http://cpp.training/ Slide 384
Scott Meyers, Software Development Consultant Kalb for NVIDIA Copyrighted material,
http://www.aristeia.com/ http://cpp.training/ all rights reserved.
Topics From Effective C++ Programming
Scott Meyers, Software Development Consultant Kalb for NVIDIA Copyrighted material, all rights reserved.
http://www.aristeia.com/ http://cpp.training/ Slide 385
Guideline
Prefer vector and string to dynamically allocated arrays.
Scott Meyers, Software Development Consultant Kalb for NVIDIA Copyrighted material, all rights reserved.
http://www.aristeia.com/ http://cpp.training/ Slide 387
Scott Meyers, Software Development Consultant Kalb for NVIDIA Copyrighted material,
http://www.aristeia.com/ http://cpp.training/ all rights reserved.
Topics From Effective C++ Programming
std::string alphabet{"abcdefghijklmnopqrstuvwxyz”};
std::string s;
for (auto j{1}; j <=1000; ++j)
s += alphabet; // ditto for s
This is very convenient.
Scott Meyers, Software Development Consultant Kalb for NVIDIA Copyrighted material, all rights reserved.
http://www.aristeia.com/ http://cpp.training/ Slide 388
Scott Meyers, Software Development Consultant Kalb for NVIDIA Copyrighted material, all rights reserved.
http://www.aristeia.com/ http://cpp.training/ Slide 389
Scott Meyers, Software Development Consultant Kalb for NVIDIA Copyrighted material,
http://www.aristeia.com/ http://cpp.training/ all rights reserved.
Topics From Effective C++ Programming
Scott Meyers, Software Development Consultant Kalb for NVIDIA Copyrighted material, all rights reserved.
http://www.aristeia.com/ http://cpp.training/ Slide 390
Excess Capacity
If you know only the maximum container size and reserve that much space,
you may end up with excess capacity.
std::vector<int> v;
v.reserve(maxDataValues); // reserve maximum needed space
... // put data into v. When done, v.size()
// may be much less than v.capacity()
std::string s;
s.reserve(maxNumChars); // reserve maximum needed space
... // again, s.size() could be much less
// than s.capacity()
Scott Meyers, Software Development Consultant Kalb for NVIDIA Copyrighted material, all rights reserved.
http://www.aristeia.com/ http://cpp.training/ Slide 391
Scott Meyers, Software Development Consultant Kalb for NVIDIA Copyrighted material,
http://www.aristeia.com/ http://cpp.training/ all rights reserved.
Topics From Effective C++ Programming
shrink_to_fit()
C++11 introduces a shrink_to_fit() member function for vector, string, and
deque.
To understand what it (probably) does, let’s review ”the swap trick” from
Classic C++:
temp
Scott Meyers, Software Development Consultant Kalb for NVIDIA Copyrighted material, all rights reserved.
http://www.aristeia.com/ http://cpp.training/ Slide 393
Scott Meyers, Software Development Consultant Kalb for NVIDIA Copyrighted material,
http://www.aristeia.com/ http://cpp.training/ all rights reserved.
Topics From Effective C++ Programming
Scott Meyers, Software Development Consultant Kalb for NVIDIA Copyrighted material, all rights reserved.
http://www.aristeia.com/ http://cpp.training/ Slide 394
Guidelines
Use reserve to minimize memory reallocations for vector and string.
Use shrink_to_fit() (or “the swap trick” in Classic C++) to perform “shrink
to fit” on vectors and strings.
Scott Meyers, Software Development Consultant Kalb for NVIDIA Copyrighted material, all rights reserved.
http://www.aristeia.com/ http://cpp.training/ Slide 395
Scott Meyers, Software Development Consultant Kalb for NVIDIA Copyrighted material,
http://www.aristeia.com/ http://cpp.training/ all rights reserved.
Topics From Effective C++ Programming
Scott Meyers, Software Development Consultant Kalb for NVIDIA Copyrighted material, all rights reserved.
http://www.aristeia.com/ http://cpp.training/ Slide 396
Scott Meyers, Software Development Consultant Kalb for NVIDIA Copyrighted material, all rights reserved.
http://www.aristeia.com/ http://cpp.training/ Slide 397
Scott Meyers, Software Development Consultant Kalb for NVIDIA Copyrighted material,
http://www.aristeia.com/ http://cpp.training/ all rights reserved.
Topics From Effective C++ Programming
Scott Meyers, Software Development Consultant Kalb for NVIDIA Copyrighted material, all rights reserved.
http://www.aristeia.com/ http://cpp.training/ Slide 399
Scott Meyers, Software Development Consultant Kalb for NVIDIA Copyrighted material,
http://www.aristeia.com/ http://cpp.training/ all rights reserved.
Topics From Effective C++ Programming
Scott Meyers, Software Development Consultant Kalb for NVIDIA Copyrighted material, all rights reserved.
http://www.aristeia.com/ http://cpp.training/ Slide 400
Scott Meyers, Software Development Consultant Kalb for NVIDIA Copyrighted material,
http://www.aristeia.com/ http://cpp.training/ all rights reserved.
Topics From Effective C++ Programming
Scott Meyers, Software Development Consultant Kalb for NVIDIA Copyrighted material, all rights reserved.
http://www.aristeia.com/ http://cpp.training/ Slide 402
Scott Meyers, Software Development Consultant Kalb for NVIDIA Copyrighted material, all rights reserved.
http://www.aristeia.com/ http://cpp.training/ Slide 403
Scott Meyers, Software Development Consultant Kalb for NVIDIA Copyrighted material,
http://www.aristeia.com/ http://cpp.training/ all rights reserved.
Topics From Effective C++ Programming
Guideline
Know how to exchange vector and string data with legacy APIs.
Scott Meyers, Software Development Consultant Kalb for NVIDIA Copyrighted material, all rights reserved.
http://www.aristeia.com/ http://cpp.training/ Slide 404
Scott Meyers, Software Development Consultant Kalb for NVIDIA Copyrighted material, all rights reserved.
http://www.aristeia.com/ http://cpp.training/ Slide 405
Scott Meyers, Software Development Consultant Kalb for NVIDIA Copyrighted material,
http://www.aristeia.com/ http://cpp.training/ all rights reserved.
Topics From Effective C++ Programming
Associative Containers
Scott Meyers, Software Development Consultant Kalb for NVIDIA Copyrighted material, all rights reserved.
http://www.aristeia.com/ http://cpp.training/ Slide 406
Scott Meyers, Software Development Consultant Kalb for NVIDIA Copyrighted material, all rights reserved.
http://www.aristeia.com/ http://cpp.training/ Slide 407
Scott Meyers, Software Development Consultant Kalb for NVIDIA Copyrighted material,
http://www.aristeia.com/ http://cpp.training/ all rights reserved.
Topics From Effective C++ Programming
Scott Meyers, Software Development Consultant Kalb for NVIDIA Copyrighted material, all rights reserved.
http://www.aristeia.com/ http://cpp.training/ Slide 408
Scott Meyers, Software Development Consultant Kalb for NVIDIA Copyrighted material, all rights reserved.
http://www.aristeia.com/ http://cpp.training/ Slide 409
Scott Meyers, Software Development Consultant Kalb for NVIDIA Copyrighted material,
http://www.aristeia.com/ http://cpp.training/ all rights reserved.
Topics From Effective C++ Programming
Scott Meyers, Software Development Consultant Kalb for NVIDIA Copyrighted material, all rights reserved.
http://www.aristeia.com/ http://cpp.training/ Slide 410
Scott Meyers, Software Development Consultant Kalb for NVIDIA Copyrighted material, all rights reserved.
http://www.aristeia.com/ http://cpp.training/ Slide 411
Scott Meyers, Software Development Consultant Kalb for NVIDIA Copyrighted material,
http://www.aristeia.com/ http://cpp.training/ all rights reserved.
Topics From Effective C++ Programming
Scott Meyers, Software Development Consultant Kalb for NVIDIA Copyrighted material, all rights reserved.
http://www.aristeia.com/ http://cpp.training/ Slide 412
Guideline
Always have comparison functions return false for equal values.
Scott Meyers, Software Development Consultant Kalb for NVIDIA Copyrighted material, all rights reserved.
http://www.aristeia.com/ http://cpp.training/ Slide 413
Scott Meyers, Software Development Consultant Kalb for NVIDIA Copyrighted material,
http://www.aristeia.com/ http://cpp.training/ all rights reserved.
Topics From Effective C++ Programming
Scott Meyers, Software Development Consultant Kalb for NVIDIA Copyrighted material, all rights reserved.
http://www.aristeia.com/ http://cpp.training/ Slide 414
Scott Meyers, Software Development Consultant Kalb for NVIDIA Copyrighted material, all rights reserved.
http://www.aristeia.com/ http://cpp.training/ Slide 415
Scott Meyers, Software Development Consultant Kalb for NVIDIA Copyrighted material,
http://www.aristeia.com/ http://cpp.training/ all rights reserved.
Topics From Effective C++ Programming
Scott Meyers, Software Development Consultant Kalb for NVIDIA Copyrighted material, all rights reserved.
http://www.aristeia.com/ http://cpp.training/ Slide 416
Scott Meyers, Software Development Consultant Kalb for NVIDIA Copyrighted material, all rights reserved.
http://www.aristeia.com/ http://cpp.training/ Slide 417
Scott Meyers, Software Development Consultant Kalb for NVIDIA Copyrighted material,
http://www.aristeia.com/ http://cpp.training/ all rights reserved.
Topics From Effective C++ Programming
Even when the cast works, it’s critical that only non-key parts of the object
are modified.
§ If a key part is modified, the container may become corrupted.
Scott Meyers, Software Development Consultant Kalb for NVIDIA Copyrighted material, all rights reserved.
http://www.aristeia.com/ http://cpp.training/ Slide 418
Safe Modification of
Associative Container Elements
A safe, portable, cast-less way to change values in associative containers
works this way:
1. Find the container element you want to change.
2. Make a copy of it.
3. Modify the copy so it has the value you want.
4. Erase the element from the container.
5. Insert the copy into the container.
w Where applicable, use the iterator from Step 1 as a hint to insert.
Scott Meyers, Software Development Consultant Kalb for NVIDIA Copyrighted material, all rights reserved.
http://www.aristeia.com/ http://cpp.training/ Slide 419
Scott Meyers, Software Development Consultant Kalb for NVIDIA Copyrighted material,
http://www.aristeia.com/ http://cpp.training/ all rights reserved.
Topics From Effective C++ Programming
Guideline
Be wary of in-place key modification.
Scott Meyers, Software Development Consultant Kalb for NVIDIA Copyrighted material, all rights reserved.
http://www.aristeia.com/ http://cpp.training/ Slide 421
Scott Meyers, Software Development Consultant Kalb for NVIDIA Copyrighted material,
http://www.aristeia.com/ http://cpp.training/ all rights reserved.
Topics From Effective C++ Programming
Scott Meyers, Software Development Consultant Kalb for NVIDIA Copyrighted material, all rights reserved.
http://www.aristeia.com/ http://cpp.training/ Slide 422
Scott Meyers, Software Development Consultant Kalb for NVIDIA Copyrighted material, all rights reserved.
http://www.aristeia.com/ http://cpp.training/ Slide 423
Scott Meyers, Software Development Consultant Kalb for NVIDIA Copyrighted material,
http://www.aristeia.com/ http://cpp.training/ all rights reserved.
Topics From Effective C++ Programming
Scott Meyers, Software Development Consultant Kalb for NVIDIA Copyrighted material, all rights reserved.
http://www.aristeia.com/ http://cpp.training/ Slide 424
Scott Meyers, Software Development Consultant Kalb for NVIDIA Copyrighted material, all rights reserved.
http://www.aristeia.com/ http://cpp.training/ Slide 425
Scott Meyers, Software Development Consultant Kalb for NVIDIA Copyrighted material,
http://www.aristeia.com/ http://cpp.training/ all rights reserved.
Topics From Effective C++ Programming
Scott Meyers, Software Development Consultant Kalb for NVIDIA Copyrighted material, all rights reserved.
http://www.aristeia.com/ http://cpp.training/ Slide 426
Scott Meyers, Software Development Consultant Kalb for NVIDIA Copyrighted material, all rights reserved.
http://www.aristeia.com/ http://cpp.training/ Slide 427
Scott Meyers, Software Development Consultant Kalb for NVIDIA Copyrighted material,
http://www.aristeia.com/ http://cpp.training/ all rights reserved.
Topics From Effective C++ Programming
… 5 6 9 10 10 16 16 18 99 …
lower_bound(10) lower_bound(17)
upper_bound(10) upper_bound(17)
Scott Meyers, Software Development Consultant Kalb for NVIDIA Copyrighted material, all rights reserved.
http://www.aristeia.com/ http://cpp.training/ Slide 428
Scott Meyers, Software Development Consultant Kalb for NVIDIA Copyrighted material, all rights reserved.
http://www.aristeia.com/ http://cpp.training/ Slide 429
Scott Meyers, Software Development Consultant Kalb for NVIDIA Copyrighted material,
http://www.aristeia.com/ http://cpp.training/ all rights reserved.
Topics From Effective C++ Programming
Scott Meyers, Software Development Consultant Kalb for NVIDIA Copyrighted material, all rights reserved.
http://www.aristeia.com/ http://cpp.training/ Slide 430
Scott Meyers, Software Development Consultant Kalb for NVIDIA Copyrighted material, all rights reserved.
http://www.aristeia.com/ http://cpp.training/ Slide 431
Scott Meyers, Software Development Consultant Kalb for NVIDIA Copyrighted material,
http://www.aristeia.com/ http://cpp.training/ all rights reserved.
Topics From Effective C++ Programming
Scott Meyers, Software Development Consultant Kalb for NVIDIA Copyrighted material, all rights reserved.
http://www.aristeia.com/ http://cpp.training/ Slide 432
Scott Meyers, Software Development Consultant Kalb for NVIDIA Copyrighted material, all rights reserved.
http://www.aristeia.com/ http://cpp.training/ Slide 433
Scott Meyers, Software Development Consultant Kalb for NVIDIA Copyrighted material,
http://www.aristeia.com/ http://cpp.training/ all rights reserved.
Topics From Effective C++ Programming
Scott Meyers, Software Development Consultant Kalb for NVIDIA Copyrighted material, all rights reserved.
http://www.aristeia.com/ http://cpp.training/ Slide 434
Scott Meyers, Software Development Consultant Kalb for NVIDIA Copyrighted material, all rights reserved.
http://www.aristeia.com/ http://cpp.training/ Slide 435
Scott Meyers, Software Development Consultant Kalb for NVIDIA Copyrighted material,
http://www.aristeia.com/ http://cpp.training/ all rights reserved.
Topics From Effective C++ Programming
Scott Meyers, Software Development Consultant Kalb for NVIDIA Copyrighted material, all rights reserved.
http://www.aristeia.com/ http://cpp.training/ Slide 436
Guideline
Know when a sorted vector is superior to a standard associative container.
Scott Meyers, Software Development Consultant Kalb for NVIDIA Copyrighted material, all rights reserved.
http://www.aristeia.com/ http://cpp.training/ Slide 437
Scott Meyers, Software Development Consultant Kalb for NVIDIA Copyrighted material,
http://www.aristeia.com/ http://cpp.training/ all rights reserved.
Topics From Effective C++ Programming
Hashed Tables
To avoid backward-compatibility issues and to emphasize the containers’
unsorted nature, the names are
§ unordered_set and unordered_multiset
§ unordered_map and unordered_multimap
These are specified so as to be largely compatible with existing
implementations:
§ E.g., forward iterators are required, but bidirectional ones are allowed.
§ E.g., incremental expansion is allowed, but not required.
Scott Meyers, Software Development Consultant Kalb for NVIDIA Copyrighted material, all rights reserved.
http://www.aristeia.com/ http://cpp.training/ Slide 438
Hash Tables
§ Declared in <unordered_set> and <unordered_map>.
Æ Default hashing functionality declared in <functional>.
§ Designed not to conflict with pre-TR1/C++11 implementations.
Æ I.e., hash_set, hash_map, hash_multiset, hash_multimap.
w Interfaces vary – hence the need for standardization.
w Standard names are unordered_set, unordered_map, etc.
Æ Compatible with hash_* interfaces where possible.
§ Each bucket has its own chain of elements:
Conceptual diagrams!
Implementations vary!
Scott Meyers, Software Development Consultant Kalb for NVIDIA Copyrighted material, all rights reserved.
http://www.aristeia.com/ http://cpp.training/ Slide 439
Scott Meyers, Software Development Consultant Kalb for NVIDIA Copyrighted material,
http://www.aristeia.com/ http://cpp.training/ all rights reserved.
Topics From Effective C++ Programming
Containers’ Characteristics
§ Usual members exist:
Æ iterator/const_iterator and other type aliases.
Æ begin/end/cbegin/cend, insert/erase, size, swap, etc.
§ Also 3 associative container functions: find, count, equal_range.
Æ lower_bound/upper_bound are absent.
§ unordered_map offers operator[] and at.
§ Most relationals not supported: no <, <=, >=, >
Æ Indeterminate ordering makes these too expensive.
Æ == and != do exist: result based on content, not ordering.
w Expected complexity O(n); worse-case is O(n2).
§ Only forward iteration is provided.
Æ No reverse_iterators, no rbegin/rend/crbegin/crend.
Scott Meyers, Software Development Consultant Kalb for NVIDIA Copyrighted material, all rights reserved.
http://www.aristeia.com/ http://cpp.training/ Slide 441
Scott Meyers, Software Development Consultant Kalb for NVIDIA Copyrighted material,
http://www.aristeia.com/ http://cpp.training/ all rights reserved.
Topics From Effective C++ Programming
Scott Meyers, Software Development Consultant Kalb for NVIDIA Copyrighted material, all rights reserved.
http://www.aristeia.com/ http://cpp.training/ Slide 442
Hashing Functions
Defaults are provided for built-in, string, and smart pointer types:
struct Widget { … };
std::unordered_set<int> si; // all use default hash
std::unordered_multiset<double> md; // func for shown types
std::unordered_map<std::wstring, int>mwi;
std::unordered_multimap<Widget*, std::string> w; // May not do what you
// want!
std::unordered_multimap<std::unique_ptr<Widget>, std::string> mm2;
Also for these less commonly used types:
§ std::vector<bool>
§ std::bitset
§ std::thread::id
§ std::error_code
§ std::type_index
Scott Meyers, Software Development Consultant Kalb for NVIDIA Copyrighted material, all rights reserved.
http://www.aristeia.com/ http://cpp.training/ Slide 443
Scott Meyers, Software Development Consultant Kalb for NVIDIA Copyrighted material,
http://www.aristeia.com/ http://cpp.training/ all rights reserved.
Topics From Effective C++ Programming
Hashing Functions
To override a default or hash a UDT, specialize hash<T> or create a custom
function object:
template<>
struct std::hash<Widget> {
using argument_type = Widget;
using result_type = std::size_t;
std::size_t operator()(Widget const& w) const { … };
};
std::unordered_set<Widget> sw;
struct IntHasher {
std::size_t operator()(int i) const { … };
};
std::unordered_map<int, std::string, IntHasher> mis;
Scott Meyers, Software Development Consultant Kalb for NVIDIA Copyrighted material, all rights reserved.
http://www.aristeia.com/ http://cpp.training/ Slide 444
Scott Meyers, Software Development Consultant Kalb for NVIDIA Copyrighted material, all rights reserved.
http://www.aristeia.com/ http://cpp.training/ Slide 445
Scott Meyers, Software Development Consultant Kalb for NVIDIA Copyrighted material,
http://www.aristeia.com/ http://cpp.training/ all rights reserved.
Topics From Effective C++ Programming
Rehashing
Explicit rehashing can also change the bucket count and load factor.
§ Specify number of desired buckets via rehash.
§ Specify number of expected elements via reserve.
std::unordered_set<int> s;
...
auto newB(computeNewB());
s.rehash(newB); // reorganize s so that B >= newB
// and s.size()/B <= zmax
...
auto expElems(computeExpectedElements());
s.reserve(expElems); // reorganize s so that expElems/B <= zmax
Rehashing (implicitly or explicitly) invalidates iterators.
§ But not pointers or references.
Scott Meyers, Software Development Consultant Kalb for NVIDIA Copyrighted material, all rights reserved.
http://www.aristeia.com/ http://cpp.training/ Slide 446
Scott Meyers, Software Development Consultant Kalb for NVIDIA Copyrighted material, all rights reserved.
http://www.aristeia.com/ http://cpp.training/ Slide 447
Scott Meyers, Software Development Consultant Kalb for NVIDIA Copyrighted material,
http://www.aristeia.com/ http://cpp.training/ all rights reserved.
Topics From Effective C++ Programming
Scott Meyers, Software Development Consultant Kalb for NVIDIA Copyrighted material, all rights reserved.
http://www.aristeia.com/ http://cpp.training/ Slide 448
Guideline
Familiarize yourself with the hashed containers.
Scott Meyers, Software Development Consultant Kalb for NVIDIA Copyrighted material, all rights reserved.
http://www.aristeia.com/ http://cpp.training/ Slide 449
Scott Meyers, Software Development Consultant Kalb for NVIDIA Copyrighted material,
http://www.aristeia.com/ http://cpp.training/ all rights reserved.
Topics From Effective C++ Programming
Scott Meyers, Software Development Consultant Kalb for NVIDIA Copyrighted material, all rights reserved.
http://www.aristeia.com/ http://cpp.training/ Slide 450
Bjarne concurs.
Scott Meyers, Software Development Consultant Kalb for NVIDIA Copyrighted material,
http://www.aristeia.com/ http://cpp.training/ all rights reserved.
Topics From Effective C++ Programming
Scott Meyers, Software Development Consultant Kalb for NVIDIA Copyrighted material, all rights reserved.
http://www.aristeia.com/ http://cpp.training/ Slide 453
Scott Meyers, Software Development Consultant Kalb for NVIDIA Copyrighted material,
http://www.aristeia.com/ http://cpp.training/ all rights reserved.
Topics From Effective C++ Programming
Scott Meyers, Software Development Consultant Kalb for NVIDIA Copyrighted material, all rights reserved.
http://www.aristeia.com/ http://cpp.training/ Slide 454
Callable Entities
Something that can be called like a function:
§ Functions, function pointers, function references:
void f(int x); // function
void (*fp)(int) {f}; // function pointer
int val;
…
f(val); // call f
fp(val); // call *fp
Scott Meyers, Software Development Consultant Kalb for NVIDIA Copyrighted material, all rights reserved.
http://www.aristeia.com/ http://cpp.training/ Slide 455
Scott Meyers, Software Development Consultant Kalb for NVIDIA Copyrighted material,
http://www.aristeia.com/ http://cpp.training/ all rights reserved.
Topics From Effective C++ Programming
Callable Entities
§ Objects implicitly convertible to one of those:
struct Widget {
using FuncPtr = void (*)(int);
operator FuncPtr() const; // conversion to function ptr
…
};
Widget w; // object with conversion to func ptr
int val;
…
w(val); // “call” w, i.e.,
// invoke w.operator FuncPtr()
Scott Meyers, Software Development Consultant Kalb for NVIDIA Copyrighted material, all rights reserved.
http://www.aristeia.com/ http://cpp.training/ Slide 456
Callable Entities
§ Function objects (including closures):
struct Gadget {
void operator()(int); // function call operator
…
};
Gadget g; // object supporting operator()
int val;
…
g(val); // “call” g, i.e., invoke w.operator()
Scott Meyers, Software Development Consultant Kalb for NVIDIA Copyrighted material, all rights reserved.
http://www.aristeia.com/ http://cpp.training/ Slide 457
Scott Meyers, Software Development Consultant Kalb for NVIDIA Copyrighted material,
http://www.aristeia.com/ http://cpp.training/ all rights reserved.
Topics From Effective C++ Programming
std::function Basics
§ Declared in <functional>.
§ std::functions are type-safe wrappers for callable entities:
std::function<int(std::string&)> f; // f refers to callable entity
// compatible with given sig.
Scott Meyers, Software Development Consultant Kalb for NVIDIA Copyrighted material, all rights reserved.
http://www.aristeia.com/ http://cpp.training/ Slide 458
Fundamental Behavior
std::function object
Scott Meyers, Software Development Consultant Kalb for NVIDIA Copyrighted material, all rights reserved.
http://www.aristeia.com/ http://cpp.training/ Slide 459
Scott Meyers, Software Development Consultant Kalb for NVIDIA Copyrighted material,
http://www.aristeia.com/ http://cpp.training/ all rights reserved.
Topics From Effective C++ Programming
Compatible Signatures
A callable entity is compatible with a function object if:
§ The function object’s parameter types can be implicitly converted to the
entity’s parameter types.
§ The entity’s return type can be implicitly converted to the function
object’s.
std::function object
Scott Meyers, Software Development Consultant Kalb for NVIDIA Copyrighted material, all rights reserved.
http://www.aristeia.com/ http://cpp.training/ Slide 460
Scott Meyers, Software Development Consultant Kalb for NVIDIA Copyrighted material,
http://www.aristeia.com/ http://cpp.training/ all rights reserved.
Topics From Effective C++ Programming
Scott Meyers, Software Development Consultant Kalb for NVIDIA Copyrighted material, all rights reserved.
http://www.aristeia.com/ http://cpp.training/ Slide 462
Scott Meyers, Software Development Consultant Kalb for NVIDIA Copyrighted material, all rights reserved.
http://www.aristeia.com/ http://cpp.training/ Slide 463
Scott Meyers, Software Development Consultant Kalb for NVIDIA Copyrighted material,
http://www.aristeia.com/ http://cpp.training/ all rights reserved.
Topics From Effective C++ Programming
Scott Meyers, Software Development Consultant Kalb for NVIDIA Copyrighted material, all rights reserved.
http://www.aristeia.com/ http://cpp.training/ Slide 464
function Summary
§ function objects are generalizations of function pointers.
§ Can refer to any callable entity with a compatible signature.
§ Especially useful for callback interfaces.
§ Explicitly disallow tests for equality or inequality.
Scott Meyers, Software Development Consultant Kalb for NVIDIA Copyrighted material, all rights reserved.
http://www.aristeia.com/ http://cpp.training/ Slide 465
Scott Meyers, Software Development Consultant Kalb for NVIDIA Copyrighted material,
http://www.aristeia.com/ http://cpp.training/ all rights reserved.
Topics From Effective C++ Programming
Lambda Expressions
Scott Meyers, Software Development Consultant Kalb for NVIDIA Copyrighted material, all rights reserved.
http://www.aristeia.com/ http://cpp.training/ Slide 466
Lambda Expressions
A quick way to create function objects at their point of use.
std::vector<int> v;
…
auto it(std::find_if( v.cbegin(), v.cend(),
[](int i) { return i > 0 && i < 10; }));
Essentially generates:
struct MagicType1 {
bool operator()(int i) const { return i > 0 && i < 10; }
};
auto it(std::find_if( v.cbegin(), v.cend(), MagicType1{}));
Scott Meyers, Software Development Consultant Kalb for NVIDIA Copyrighted material, all rights reserved.
http://www.aristeia.com/ http://cpp.training/ Slide 467
Scott Meyers, Software Development Consultant Kalb for NVIDIA Copyrighted material,
http://www.aristeia.com/ http://cpp.training/ all rights reserved.
Topics From Effective C++ Programming
Lambda Expressions
Another example:
using SPWidget = std::shared_ptr<Widget>;
std::deque<SPWidget> d;
…
std::sort(begin(d), end(d),
[](SPWidget const& sp1, SPWidget const& sp2)
{ return *sp1 < *sp2; });
Essentially generates:
struct MagicType2 {
bool operator()(SPWidget const& p1, SPWidget const& p2) const
{ return *p1 < *p2; }
};
std::sort(begin(d), end(d), MagicType2{});
Function objects created through lambda expressions are closures.
Scott Meyers, Software Development Consultant Kalb for NVIDIA Copyrighted material, all rights reserved.
http://www.aristeia.com/ http://cpp.training/ Slide 468
Scott Meyers, Software Development Consultant Kalb for NVIDIA Copyrighted material, all rights reserved.
http://www.aristeia.com/ http://cpp.training/ Slide 469
Scott Meyers, Software Development Consultant Kalb for NVIDIA Copyrighted material,
http://www.aristeia.com/ http://cpp.training/ all rights reserved.
Topics From Effective C++ Programming
Scott Meyers, Software Development Consultant Kalb for NVIDIA Copyrighted material, all rights reserved.
http://www.aristeia.com/ http://cpp.training/ Slide 470
Scott Meyers, Software Development Consultant Kalb for NVIDIA Copyrighted material, all rights reserved.
http://www.aristeia.com/ http://cpp.training/ Slide 471
Scott Meyers, Software Development Consultant Kalb for NVIDIA Copyrighted material,
http://www.aristeia.com/ http://cpp.training/ all rights reserved.
Topics From Effective C++ Programming
Scott Meyers, Software Development Consultant Kalb for NVIDIA Copyrighted material, all rights reserved.
http://www.aristeia.com/ http://cpp.training/ Slide 472
Scott Meyers, Software Development Consultant Kalb for NVIDIA Copyrighted material, all rights reserved.
http://www.aristeia.com/ http://cpp.training/ Slide 473
Scott Meyers, Software Development Consultant Kalb for NVIDIA Copyrighted material,
http://www.aristeia.com/ http://cpp.training/ all rights reserved.
Topics From Effective C++ Programming
Scott Meyers, Software Development Consultant Kalb for NVIDIA Copyrighted material, all rights reserved.
http://www.aristeia.com/ http://cpp.training/ Slide 474
Scott Meyers, Software Development Consultant Kalb for NVIDIA Copyrighted material, all rights reserved.
http://www.aristeia.com/ http://cpp.training/ Slide 475
Scott Meyers, Software Development Consultant Kalb for NVIDIA Copyrighted material,
http://www.aristeia.com/ http://cpp.training/ all rights reserved.
Topics From Effective C++ Programming
Scott Meyers, Software Development Consultant Kalb for NVIDIA Copyrighted material, all rights reserved.
http://www.aristeia.com/ http://cpp.training/ Slide 476
Scott Meyers, Software Development Consultant Kalb for NVIDIA Copyrighted material, all rights reserved.
http://www.aristeia.com/ http://cpp.training/ Slide 477
Scott Meyers, Software Development Consultant Kalb for NVIDIA Copyrighted material,
http://www.aristeia.com/ http://cpp.training/ all rights reserved.
Topics From Effective C++ Programming
Scott Meyers, Software Development Consultant Kalb for NVIDIA Copyrighted material, all rights reserved.
http://www.aristeia.com/ http://cpp.training/ Slide 478
Scott Meyers, Software Development Consultant Kalb for NVIDIA Copyrighted material, all rights reserved.
http://www.aristeia.com/ http://cpp.training/ Slide 479
Scott Meyers, Software Development Consultant Kalb for NVIDIA Copyrighted material,
http://www.aristeia.com/ http://cpp.training/ all rights reserved.
Topics From Effective C++ Programming
Scott Meyers, Software Development Consultant Kalb for NVIDIA Copyrighted material, all rights reserved.
http://www.aristeia.com/ http://cpp.training/ Slide 480
Scott Meyers, Software Development Consultant Kalb for NVIDIA Copyrighted material, all rights reserved.
http://www.aristeia.com/ http://cpp.training/ Slide 481
Scott Meyers, Software Development Consultant Kalb for NVIDIA Copyrighted material,
http://www.aristeia.com/ http://cpp.training/ all rights reserved.
Topics From Effective C++ Programming
Scott Meyers, Software Development Consultant Kalb for NVIDIA Copyrighted material, all rights reserved.
http://www.aristeia.com/ http://cpp.training/ Slide 482
Scott Meyers, Software Development Consultant Kalb for NVIDIA Copyrighted material, all rights reserved.
http://www.aristeia.com/ http://cpp.training/ Slide 483
Scott Meyers, Software Development Consultant Kalb for NVIDIA Copyrighted material,
http://www.aristeia.com/ http://cpp.training/ all rights reserved.
Topics From Effective C++ Programming
Scott Meyers, Software Development Consultant Kalb for NVIDIA Copyrighted material, all rights reserved.
http://www.aristeia.com/ http://cpp.training/ Slide 484
Scott Meyers, Software Development Consultant Kalb for NVIDIA Copyrighted material, all rights reserved.
http://www.aristeia.com/ http://cpp.training/ Slide 485
Scott Meyers, Software Development Consultant Kalb for NVIDIA Copyrighted material,
http://www.aristeia.com/ http://cpp.training/ all rights reserved.
Topics From Effective C++ Programming
Scott Meyers, Software Development Consultant Kalb for NVIDIA Copyrighted material, all rights reserved.
http://www.aristeia.com/ http://cpp.training/ Slide 486
Scott Meyers, Software Development Consultant Kalb for NVIDIA Copyrighted material, all rights reserved.
http://www.aristeia.com/ http://cpp.training/ Slide 487
Scott Meyers, Software Development Consultant Kalb for NVIDIA Copyrighted material,
http://www.aristeia.com/ http://cpp.training/ all rights reserved.
Topics From Effective C++ Programming
Scott Meyers, Software Development Consultant Kalb for NVIDIA Copyrighted material, all rights reserved.
http://www.aristeia.com/ http://cpp.training/ Slide 488
Scott Meyers, Software Development Consultant Kalb for NVIDIA Copyrighted material, all rights reserved.
http://www.aristeia.com/ http://cpp.training/ Slide 489
Scott Meyers, Software Development Consultant Kalb for NVIDIA Copyrighted material,
http://www.aristeia.com/ http://cpp.training/ all rights reserved.
Topics From Effective C++ Programming
Scott Meyers, Software Development Consultant Kalb for NVIDIA Copyrighted material, all rights reserved.
http://www.aristeia.com/ http://cpp.training/ Slide 490
Capture Guidance
Explicitly list variables to capture.
§ Compilers reject un-capturable variables.
Æ Struct data members.
Æ Variables of static storage duration.
§ Reduces risk of dangling captures.
§ Reduces false sense of security regarding closures being self-contained.
Scott Meyers, Software Development Consultant Kalb for NVIDIA Copyrighted material, all rights reserved.
http://www.aristeia.com/ http://cpp.training/ Slide 491
Scott Meyers, Software Development Consultant Kalb for NVIDIA Copyrighted material,
http://www.aristeia.com/ http://cpp.training/ all rights reserved.
Topics From Effective C++ Programming
Guideline
Avoid default capture modes.
Scott Meyers, Software Development Consultant Kalb for NVIDIA Copyrighted material, all rights reserved.
http://www.aristeia.com/ http://cpp.training/ Slide 493
Scott Meyers, Software Development Consultant Kalb for NVIDIA Copyrighted material,
http://www.aristeia.com/ http://cpp.training/ all rights reserved.
Topics From Effective C++ Programming
Scott Meyers, Software Development Consultant Kalb for NVIDIA Copyrighted material, all rights reserved.
http://www.aristeia.com/ http://cpp.training/ Slide 494
Template Challenge
Let’s write a function template from scratch.
Don’t worry it’s the simplest function in the world: add()—it adds two things:
template <class T>
T add(T a, T b)
{ return a + b; }
T is an unknown type so it might be expensive to copy, so:
template <class T>
T add(T const& a, T const& b)
{ return a + b; }
Easy-peasy, right? The simplest function in the world.
Wait, but if we want to add two things of different types?
template <class T, class U>
T add(T const& a, U const& b)
{ return a + b; }
Scott Meyers, Software Development Consultant Kalb for NVIDIA Copyrighted material,
http://www.aristeia.com/ http://cpp.training/ all rights reserved.
Topics From Effective C++ Programming
Template Challenge
What is wrong with this?
template <class T, class U>
T add(T const& a, U const& b)
{ return a + b; }
Template Challenge
What is wrong with this?
template <class T, class U>
T add(T const& a, U const& b)
{ return a + b; }
What should the return type be?
• We can’t assume it is the type of the first parameter.
• We can’t even assume it is the type of either parameter.
• Adding a char and a short results in an int.
The return type should be whatever you get when you add a T and a U.
How do we say that?
template <class T, class U>
decltype(T + U) add(T const& a, U const& b)
{ return a + b; }
Scott Meyers, Software Development Consultant Kalb for NVIDIA Copyrighted material,
http://www.aristeia.com/ http://cpp.training/ all rights reserved.
Topics From Effective C++ Programming
Template Challenge
What is wrong with this?
template <class T, class U>
decltype(T + U) add(T const& a, U const& b)
{ return a + b; }
It doesn’t compile! Why not?
decltype works on expressions. You can’t add two types.
How can we fix this?
template <class T, class U>
decltype(a + b) add(T const& a, U const& b)
{ return a + b; }
Template Challenge
What is wrong with this?
template <class T, class U>
decltype(a + b) add(T const& a, U const& b)
{ return a + b; }
It doesn’t compile! Why not?
a and b in decltype(a + b) are not defined.
How can we fix this?
template <class T, class U>
auto add(T const& a, U const& b) -> decltype(a + b)
{ return a + b; }
Scott Meyers, Software Development Consultant Kalb for NVIDIA Copyrighted material,
http://www.aristeia.com/ http://cpp.training/ all rights reserved.
Topics From Effective C++ Programming
Template Challenge
This is the simplest template in the world, but it couldn’t be written in
Classic C++ because we need decltype and trailing return type function
declarations.
template <class T, class U>
auto add(T const& a, U const& b) -> decltype(a + b)
{ return a + b; }
Scott Meyers, Software Development Consultant Kalb for NVIDIA Copyrighted material,
http://www.aristeia.com/ http://cpp.training/ all rights reserved.
Topics From Effective C++ Programming
Scott Meyers, Software Development Consultant Kalb for NVIDIA Copyrighted material, all rights reserved.
http://www.aristeia.com/ http://cpp.training/ Slide 502
Storing Closures
Closure types not specified, but two easy ways to store closures:
§ auto:
auto multipleOf5([](long x) { return x % 5 == 0; });
std::vector<long> vl;
…
vl.erase(std::remove_if(begin(vl), end(vl), multipleOf5), end(vl));
§ std::function:
std::function<bool(long)> multipleOf5{ // see next page for syntax
[](long x) { return x % 5 == 0; }};
…
vl.erase(std::remove_if(begin(vl), end(vl), multipleOf5), end(vl));
Scott Meyers, Software Development Consultant Kalb for NVIDIA Copyrighted material, all rights reserved.
http://www.aristeia.com/ http://cpp.training/ Slide 503
Scott Meyers, Software Development Consultant Kalb for NVIDIA Copyrighted material,
http://www.aristeia.com/ http://cpp.training/ all rights reserved.
Topics From Effective C++ Programming
Scott Meyers, Software Development Consultant Kalb for NVIDIA Copyrighted material, all rights reserved.
http://www.aristeia.com/ http://cpp.training/ Slide 504
Storing Closures
auto more efficient than std::function, but not always applicable.
§ Not allowed for function parameters or return types:
void useIt(auto func); // error!
void useIt(std::function<bool(long)> func); // fine
template<class Func>
void useIt(Func func); // fine, but generates
// multiple functions
Scott Meyers, Software Development Consultant Kalb for NVIDIA Copyrighted material, all rights reserved.
http://www.aristeia.com/ http://cpp.training/ Slide 505
Scott Meyers, Software Development Consultant Kalb for NVIDIA Copyrighted material,
http://www.aristeia.com/ http://cpp.training/ all rights reserved.
Topics From Effective C++ Programming
Storing Closures
§ Not allowed for struct data members:
struct Widget {
private:
auto func; // error!
...
};
struct Widget {
private:
std::function<bool(long)> f; // fine
...
};
Scott Meyers, Software Development Consultant Kalb for NVIDIA Copyrighted material, all rights reserved.
http://www.aristeia.com/ http://cpp.training/ Slide 506
Scott Meyers, Software Development Consultant Kalb for NVIDIA Copyrighted material, all rights reserved.
http://www.aristeia.com/ http://cpp.training/ Slide 507
Scott Meyers, Software Development Consultant Kalb for NVIDIA Copyrighted material,
http://www.aristeia.com/ http://cpp.training/ all rights reserved.
Topics From Effective C++ Programming
Scott Meyers, Software Development Consultant Kalb for NVIDIA Copyrighted material, all rights reserved.
http://www.aristeia.com/ http://cpp.training/ Slide 508
Scott Meyers, Software Development Consultant Kalb for NVIDIA Copyrighted material, all rights reserved.
http://www.aristeia.com/ http://cpp.training/ Slide 509
Scott Meyers, Software Development Consultant Kalb for NVIDIA Copyrighted material,
http://www.aristeia.com/ http://cpp.training/ all rights reserved.
Topics From Effective C++ Programming
Lambdas in C++14
“Polymorphic” parameters permitted:
std::vector<std::shared_ptr<Widget>> vspw;
…
std::sort( begin(vspw), end(vspw),
[]( std::shared_ptr<Widget> const& p1, // C++11
std::shared_ptr<Widget> const& p2)
{ return *p1 < *p2; });
std::sort( begin(vspw), end(vspw),
[]( auto const& p1, auto const& p2) // C++14
{ return *p1 < *p2; });
Generated structs have templatized operator()s:
struct MagicType {
template<class T1, class T2>
bool operator()(T1 const& p1, T2 const& p2) const
{ return *p1 < *p2; }
};
Scott Meyers, Software Development Consultant Kalb for NVIDIA Copyrighted material, all rights reserved.
http://www.aristeia.com/ http://cpp.training/ Slide 510
Lambdas in C++14
Return type may be deduced, even with multiple statements:
std::vector<double> v;
…
std::transform( begin(v), end(v), begin(v), // C++11
[](double d)->double // (as before)
{
makeLogEntry("std::transform", d);
return std::sqrt(std::abs(d));
});
std::transform( begin(v), end(v), begin(v), // C++14
[](double d) // (note no
{ // return type)
makeLogEntry("std::transform", d);
return std::sqrt(std::abs(d));
});
Scott Meyers, Software Development Consultant Kalb for NVIDIA Copyrighted material, all rights reserved.
http://www.aristeia.com/ http://cpp.training/ Slide 511
Scott Meyers, Software Development Consultant Kalb for NVIDIA Copyrighted material,
http://www.aristeia.com/ http://cpp.training/ all rights reserved.
Topics From Effective C++ Programming
Scott Meyers, Software Development Consultant Kalb for NVIDIA Copyrighted material, all rights reserved.
http://www.aristeia.com/ http://cpp.training/ Slide 512
Scott Meyers, Software Development Consultant Kalb for NVIDIA Copyrighted material, all rights reserved.
http://www.aristeia.com/ http://cpp.training/ Slide 513
Scott Meyers, Software Development Consultant Kalb for NVIDIA Copyrighted material,
http://www.aristeia.com/ http://cpp.training/ all rights reserved.
Topics From Effective C++ Programming
std::function<void()> getFunction()
{
std::vector<Widget> vw;
… // populate vector
return [vw] { … }; // expensive to copy
}
std::function<void()> getFunction()
{
std::vector<Widget> vw;
… // populate vector
return [&vw] { … }; // inexpensive, but
} // getFunction returns
// dangling reference
Scott Meyers, Software Development Consultant Kalb for NVIDIA Copyrighted material, all rights reserved.
http://www.aristeia.com/ http://cpp.training/ Slide 514
Scott Meyers, Software Development Consultant Kalb for NVIDIA Copyrighted material, all rights reserved.
http://www.aristeia.com/ http://cpp.training/ Slide 515
Scott Meyers, Software Development Consultant Kalb for NVIDIA Copyrighted material,
http://www.aristeia.com/ http://cpp.training/ all rights reserved.
Topics From Effective C++ Programming
Scott Meyers, Software Development Consultant Kalb for NVIDIA Copyrighted material, all rights reserved.
http://www.aristeia.com/ http://cpp.training/ Slide 516
Scott Meyers, Software Development Consultant Kalb for NVIDIA Copyrighted material, all rights reserved.
http://www.aristeia.com/ http://cpp.training/ Slide 517
Scott Meyers, Software Development Consultant Kalb for NVIDIA Copyrighted material,
http://www.aristeia.com/ http://cpp.training/ all rights reserved.
Topics From Effective C++ Programming
Scott Meyers, Software Development Consultant Kalb for NVIDIA Copyrighted material, all rights reserved.
http://www.aristeia.com/ http://cpp.training/ Slide 518
Scott Meyers, Software Development Consultant Kalb for NVIDIA Copyrighted material, all rights reserved.
http://www.aristeia.com/ http://cpp.training/ Slide 519
Scott Meyers, Software Development Consultant Kalb for NVIDIA Copyrighted material,
http://www.aristeia.com/ http://cpp.training/ all rights reserved.
Topics From Effective C++ Programming
Scott Meyers, Software Development Consultant Kalb for NVIDIA Copyrighted material, all rights reserved.
http://www.aristeia.com/ http://cpp.training/ Slide 521
Scott Meyers, Software Development Consultant Kalb for NVIDIA Copyrighted material,
http://www.aristeia.com/ http://cpp.training/ all rights reserved.
Topics From Effective C++ Programming
Generated code:
struct MagicType
{
static int __lambda_call_operator_invoker(int x) {return x * x;}
int operator()(int x) const { return __lambda_call_operator_invoker(x); }
using __fptr_t = int(*)(int);
operator __fptr_t() const {return &__lambda_call_operator_invoker;}
};
Scott Meyers, Software Development Consultant Kalb for NVIDIA Copyrighted material, all rights reserved.
http://www.aristeia.com/ http://cpp.training/ Slide 524
Scott Meyers, Software Development Consultant Kalb for NVIDIA Copyrighted material,
http://www.aristeia.com/ http://cpp.training/ all rights reserved.
Topics From Effective C++ Programming
Scott Meyers, Software Development Consultant Kalb for NVIDIA Copyrighted material, all rights reserved.
http://www.aristeia.com/ http://cpp.training/ Slide 526
Lambda/Closure Summary
§ Lambda expressions generate closures.
§ Calling state can be captured by value or by reference.
Æ Avoid default capture modes
§ Return types, when specified, use trailing return type syntax.
§ Closures can be stored using auto or std::function.
Æ Be alert for dangling references/pointers in stored closures.
§ Short, clear, context-derived lambdas are best.
§ C++14 adds support for auto parameters, init captures, and less
restrictive return type deduction.
Æ To emulate init capture for moving into lambdas in C++11, hand
write a function object.
Scott Meyers, Software Development Consultant Kalb for NVIDIA Copyrighted material, all rights reserved.
http://www.aristeia.com/ http://cpp.training/ Slide 527
Scott Meyers, Software Development Consultant Kalb for NVIDIA Copyrighted material,
http://www.aristeia.com/ http://cpp.training/ all rights reserved.
Topics From Effective C++ Programming
Scott Meyers, Software Development Consultant Kalb for NVIDIA Copyrighted material, all rights reserved.
http://www.aristeia.com/ http://cpp.training/ Slide 528
Scott Meyers, Software Development Consultant Kalb for NVIDIA Copyrighted material, all rights reserved.
http://www.aristeia.com/ http://cpp.training/ Slide 529
Scott Meyers, Software Development Consultant Kalb for NVIDIA Copyrighted material,
http://www.aristeia.com/ http://cpp.training/ all rights reserved.
Topics From Effective C++ Programming
Scott Meyers, Software Development Consultant Kalb for NVIDIA Copyrighted material, all rights reserved.
http://www.aristeia.com/ http://cpp.training/ Slide 530
std::unique_ptr
Good choice for factory function returns:
struct Investment { … };
struct Bond:
Investment { … };
Stock Bond RealEstate
struct RealEstate:
Investment { … };
Scott Meyers, Software Development Consultant Kalb for NVIDIA Copyrighted material, all rights reserved.
http://www.aristeia.com/ http://cpp.training/ Slide 531
Scott Meyers, Software Development Consultant Kalb for NVIDIA Copyrighted material,
http://www.aristeia.com/ http://cpp.training/ all rights reserved.
Topics From Effective C++ Programming
std::unique_ptr
Simple client use:
{
…
auto pInvestment(makeInvestment(arguments));
…
} // *pInvestment destroyed
Works well with ownership chains:
1. Move from factory into local variable.
2. Move from local variable into container.
3. Move from container into object data member.
4. Object is destroyed.
If chain disrupted, pointed-to-object (usually) automatically destroyed.
Deleters
Deleter is function invoked when pointee is destroyed.
§ Default is delete.
§ Custom deleter can override default.
Æ Type of std::unique_ptr includes type of deleter:
auto delInvmt([](Investment* pInvestment) // custom
{ // deleter
makeLogEntry(pInvestment);
delete pInvestment;
});
template<class... Ts> // revised
std::unique_ptr<Investment, decltype(delInvmt)> // return
makeInvestment(Ts&&... params); // type
Scott Meyers, Software Development Consultant Kalb for NVIDIA Copyrighted material, all rights reserved.
http://www.aristeia.com/ http://cpp.training/ Slide 533
Scott Meyers, Software Development Consultant Kalb for NVIDIA Copyrighted material,
http://www.aristeia.com/ http://cpp.training/ all rights reserved.
Topics From Effective C++ Programming
Deleters
template<class... Ts> // from
std::unique_ptr<Investment, decltype(delInvmt)> // previous
makeInvestment(Ts&&... params) // slide
{
std::unique_ptr<Investment, decltype(delInvmt)> // ptr to be
pInv{nullptr, delInvmt}; // returned
Deleters
auto return type permits deleter to be encapsulated inside factory:
template<class... Ts> // C++14
auto makeInvestment(Ts&&... params) // only
{
auto delInvmt([](Investment* pInvestment) // now
{ // inside
makeLogEntry(pInvestment); // factory
delete pInvestment;
});
std::unique_ptr<Investment, decltype(delInvmt)> // as before
pInv{nullptr, delInvmt};
... // make pInv
// point to
// suitable
// object
return pInv; // as before
}
Scott Meyers, Software Development Consultant Kalb for NVIDIA Copyrighted material, all rights reserved.
http://www.aristeia.com/ http://cpp.training/ Slide 535
Scott Meyers, Software Development Consultant Kalb for NVIDIA Copyrighted material,
http://www.aristeia.com/ http://cpp.training/ all rights reserved.
Topics From Effective C++ Programming
Deleters
delInvmt takes pointer to base class:
auto delInvmt([](Investment* pInvestment)
{
makeLogEntry(pInvestment);
delete pInvestment;
});
Investment must thus have virtual destructor:
struct Investment {
… // essential
virtual ~Investment(); // design
… // component!
};
Scott Meyers, Software Development Consultant Kalb for NVIDIA Copyrighted material, all rights reserved.
http://www.aristeia.com/ http://cpp.training/ Slide 536
std::unique_ptr<T>
T* pointee
Scott Meyers, Software Development Consultant Kalb for NVIDIA Copyrighted material, all rights reserved.
http://www.aristeia.com/ http://cpp.training/ Slide 537
Scott Meyers, Software Development Consultant Kalb for NVIDIA Copyrighted material,
http://www.aristeia.com/ http://cpp.training/ all rights reserved.
Topics From Effective C++ Programming
T* pointee
deleter
state
Scott Meyers, Software Development Consultant Kalb for NVIDIA Copyrighted material, all rights reserved.
http://www.aristeia.com/ http://cpp.training/ Slide 538
Scott Meyers, Software Development Consultant Kalb for NVIDIA Copyrighted material, all rights reserved.
http://www.aristeia.com/ http://cpp.training/ Slide 539
Scott Meyers, Software Development Consultant Kalb for NVIDIA Copyrighted material,
http://www.aristeia.com/ http://cpp.training/ all rights reserved.
Topics From Effective C++ Programming
Scott Meyers, Software Development Consultant Kalb for NVIDIA Copyrighted material, all rights reserved.
http://www.aristeia.com/ http://cpp.training/ Slide 541
Scott Meyers, Software Development Consultant Kalb for NVIDIA Copyrighted material,
http://www.aristeia.com/ http://cpp.training/ all rights reserved.
Topics From Effective C++ Programming
Scott Meyers, Software Development Consultant Kalb for NVIDIA Copyrighted material, all rights reserved.
http://www.aristeia.com/ http://cpp.training/ Slide 542
Guideline
Use std::unique_ptr for exclusive-ownership resource management.
Scott Meyers, Software Development Consultant Kalb for NVIDIA Copyrighted material,
http://www.aristeia.com/ http://cpp.training/ all rights reserved.
Topics From Effective C++ Programming
Scott Meyers, Software Development Consultant Kalb for NVIDIA Copyrighted material, all rights reserved.
http://www.aristeia.com/ http://cpp.training/ Slide 544
Deleters
Type of deleter not part of the std::shared_ptr type.
§ Important difference from std::unique_ptr:
auto loggingDel([](Widget *pw) // custom deleter
{
makeLogEntry(pw);
delete pw;
});
std::unique_ptr< // deleter type is
Widget, decltype(loggingDel) // part of ptr type
> upw{new Widget, loggingDel};
Scott Meyers, Software Development Consultant Kalb for NVIDIA Copyrighted material,
http://www.aristeia.com/ http://cpp.training/ all rights reserved.
Topics From Effective C++ Programming
Deleters
Design nicely flexible:
auto customDeleter1([](Widget *pw) { … }); // different
auto customDeleter2([](Widget *pw) { … }); // deleter types
std::shared_ptr<Widget> pw1{new Widget,
customDeleter1};
std::shared_ptr<Widget> pw2{new Widget,
customDeleter2};
std::vector<std::shared_ptr<Widget>> // container of
vpw{pw1, pw2}; // shared_ptrs
// w/differing
// deleters
Implication:
§ Size of std::shared_ptr unaffected by size of deleter.
Æ Makes std::vector<std::shared_ptr> possible.
Scott Meyers, Software Development Consultant Kalb for NVIDIA Copyrighted material, all rights reserved.
http://www.aristeia.com/ http://cpp.training/ Slide 546
Deleters
But deleters may be arbitrarily large:
§ Stateful function objects (e.g., closures with captured state).
If sizeof(std::shared_ptr<T, BigDeleterType>) independent of
sizeof(BigDeleterType),
§ Where store BigDeleterType object for std::shared_ptr<T>?
Scott Meyers, Software Development Consultant Kalb for NVIDIA Copyrighted material, all rights reserved.
http://www.aristeia.com/ http://cpp.training/ Slide 547
Scott Meyers, Software Development Consultant Kalb for NVIDIA Copyrighted material,
http://www.aristeia.com/ http://cpp.training/ all rights reserved.
Topics From Effective C++ Programming
Control Blocks
As part of control block:
§ Object containing RC.
More detailed view of std::shared_ptr objects:
T* T Object
Control Block
RC
Weak Count
Other Data
(e.g.,
deleter,
allocator,
etc.)
Scott Meyers, Software Development Consultant Kalb for NVIDIA Copyrighted material, all rights reserved.
http://www.aristeia.com/ http://cpp.training/ Slide 548
Scott Meyers, Software Development Consultant Kalb for NVIDIA Copyrighted material, all rights reserved.
http://www.aristeia.com/ http://cpp.training/ Slide 549
Scott Meyers, Software Development Consultant Kalb for NVIDIA Copyrighted material,
http://www.aristeia.com/ http://cpp.training/ all rights reserved.
Topics From Effective C++ Programming
Scott Meyers, Software Development Consultant Kalb for NVIDIA Copyrighted material, all rights reserved.
http://www.aristeia.com/ http://cpp.training/ Slide 550
Scott Meyers, Software Development Consultant Kalb for NVIDIA Copyrighted material, all rights reserved.
http://www.aristeia.com/ http://cpp.training/ Slide 551
Scott Meyers, Software Development Consultant Kalb for NVIDIA Copyrighted material,
http://www.aristeia.com/ http://cpp.training/ all rights reserved.
Topics From Effective C++ Programming
struct Widget {
…
void process(); // Widget-processing
… // function
};
void Widget::process()
{
… // process the Widget
processedWidgets.emplace_back(this); // uh oh...
}
This is a problem waiting to happen.
Scott Meyers, Software Development Consultant Kalb for NVIDIA Copyrighted material, all rights reserved.
http://www.aristeia.com/ http://cpp.training/ Slide 552
Scott Meyers, Software Development Consultant Kalb for NVIDIA Copyrighted material, all rights reserved.
http://www.aristeia.com/ http://cpp.training/ Slide 553
Scott Meyers, Software Development Consultant Kalb for NVIDIA Copyrighted material,
http://www.aristeia.com/ http://cpp.training/ all rights reserved.
Topics From Effective C++ Programming
Scott Meyers, Software Development Consultant Kalb for NVIDIA Copyrighted material,
http://www.aristeia.com/ http://cpp.training/ all rights reserved.
Topics From Effective C++ Programming
std::enable_shared_from_this
Solution is std::enable_shared_from_this.
§ A base class (template).
Æ Uses CRTP (“Curiously Recurring Template Pattern”).
§ Inherit from it to safely convert this to a std::shared_ptr.
§ Call shared_from_this instead of using this.
struct Widget: std::enable_shared_from_this<Widget> {
…
};
void Widget::process()
{
…
processedWidgets.emplace_back(shared_from_this());
}
Scott Meyers, Software Development Consultant Kalb for NVIDIA Copyrighted material, all rights reserved.
http://www.aristeia.com/ http://cpp.training/ Slide 556
std::enable_shared_from_this
shared_from_this looks up current control block for *this.
§ If none present, UB.
Æ Implementations typically throw.
Classes using std::enable_shared_from_this often limit creation to factory
functions returning std::shared_ptrs.
§ Class instances have control blocks at birth.
§ Subsequent uses of shared_from_this hence safe.
Scott Meyers, Software Development Consultant Kalb for NVIDIA Copyrighted material, all rights reserved.
http://www.aristeia.com/ http://cpp.training/ Slide 557
Scott Meyers, Software Development Consultant Kalb for NVIDIA Copyrighted material,
http://www.aristeia.com/ http://cpp.training/ all rights reserved.
Topics From Effective C++ Programming
std::enable_shared_from_this
struct Widget: std::enable_shared_from_this<Widget> {
template<class... Ts> // factory function;
static std::shared_ptr<Widget> // calls private ctor
create(Ts&&... params);
…
void process(); // as before, uses
… // shared_from_this
private:
… // ctors
};
Scott Meyers, Software Development Consultant Kalb for NVIDIA Copyrighted material, all rights reserved.
http://www.aristeia.com/ http://cpp.training/ Slide 558
Cost Summary
§ std::shared_ptrs twice as big as raw pointers.
§ Memory for control block dynamically allocated.
Æ Typical size: 4 words + sizeof(deleter) + sizeof(allocator).
w 2 words for reference counts.
w 1 word for typed pointer to object.
w 1 word for vptr. (Pointee destruction entails virtual call.)
w Default deleter and allocator should use no memory.
Æ Cost of dynamic allocation avoided when std::make_shared used.
w It becomes part of allocation for pointee.
§ RC manipulations use atomic instructions.
Æ Incurred for copy operations, but not for moves.
§ Dereferencing cost same as for raw pointer.
Costs are reasonable for shared-ownership resource management.
§ When exclusive ownership suffices, std::unique_ptr a better choice.
Scott Meyers, Software Development Consultant Kalb for NVIDIA Copyrighted material, all rights reserved.
http://www.aristeia.com/ http://cpp.training/ Slide 559
Scott Meyers, Software Development Consultant Kalb for NVIDIA Copyrighted material,
http://www.aristeia.com/ http://cpp.training/ all rights reserved.
Topics From Effective C++ Programming
Scott Meyers, Software Development Consultant Kalb for NVIDIA Copyrighted material, all rights reserved.
http://www.aristeia.com/ http://cpp.training/ Slide 560
Scott Meyers, Software Development Consultant Kalb for NVIDIA Copyrighted material, all rights reserved.
http://www.aristeia.com/ http://cpp.training/ Slide 561
Scott Meyers, Software Development Consultant Kalb for NVIDIA Copyrighted material,
http://www.aristeia.com/ http://cpp.training/ all rights reserved.
Topics From Effective C++ Programming
Scott Meyers, Software Development Consultant Kalb for NVIDIA Copyrighted material, all rights reserved.
http://www.aristeia.com/ http://cpp.training/ Slide 562
Scott Meyers, Software Development Consultant Kalb for NVIDIA Copyrighted material, all rights reserved.
http://www.aristeia.com/ http://cpp.training/ Slide 563
Scott Meyers, Software Development Consultant Kalb for NVIDIA Copyrighted material,
http://www.aristeia.com/ http://cpp.training/ all rights reserved.
Topics From Effective C++ Programming
Scott Meyers, Software Development Consultant Kalb for NVIDIA Copyrighted material, all rights reserved.
http://www.aristeia.com/ http://cpp.training/ Slide 564
Guideline
Use std::shared_ptr for shared-ownership resource management.
Scott Meyers, Software Development Consultant Kalb for NVIDIA Copyrighted material,
http://www.aristeia.com/ http://cpp.training/ all rights reserved.
Topics From Effective C++ Programming
Scott Meyers, Software Development Consultant Kalb for NVIDIA Copyrighted material, all rights reserved.
http://www.aristeia.com/ http://cpp.training/ Slide 566
Scott Meyers, Software Development Consultant Kalb for NVIDIA Copyrighted material,
http://www.aristeia.com/ http://cpp.training/ all rights reserved.
Topics From Effective C++ Programming
Multiple Allocations
std::shared_ptr needs heap-based reference count to point to.
§ Created by first std::shared_ptr to object.
Hence
std::shared_ptr<Widget> pw{new Widget{args}};
incurs two heap allocations:
§ One for new Widget. CB
pw
§ One for control block (CB) :Widget
inside std::shared_ptr ctor).
Scott Meyers, Software Development Consultant Kalb for NVIDIA Copyrighted material, all rights reserved.
http://www.aristeia.com/ http://cpp.training/ Slide 568
Reducing Allocations
std::make_shared makes one allocation for both object and CB:
auto pw(std::make_shared<Widget>(args));
pw CB :Widget
Scott Meyers, Software Development Consultant Kalb for NVIDIA Copyrighted material, all rights reserved.
http://www.aristeia.com/ http://cpp.training/ Slide 569
Scott Meyers, Software Development Consultant Kalb for NVIDIA Copyrighted material,
http://www.aristeia.com/ http://cpp.training/ all rights reserved.
Topics From Effective C++ Programming
CB
pw
:Widget
In more detail:
Control Block
pw
:Widget
Scott Meyers, Software Development Consultant Kalb for NVIDIA Copyrighted material, all rights reserved.
http://www.aristeia.com/ http://cpp.training/ Slide 570
Still Closer
Sample implementation (Boost 1.52):
shared_ptr<T>
px T Object
pn.pi
RC
Weak Count
Optional { Deleter
Allocator
Scott Meyers, Software Development Consultant Kalb for NVIDIA Copyrighted material, all rights reserved.
http://www.aristeia.com/ http://cpp.training/ Slide 571
Scott Meyers, Software Development Consultant Kalb for NVIDIA Copyrighted material,
http://www.aristeia.com/ http://cpp.training/ all rights reserved.
Topics From Effective C++ Programming
sp CB
Object
CBs hence smaller (and faster to initialize).
Scott Meyers, Software Development Consultant Kalb for NVIDIA Copyrighted material, all rights reserved.
http://www.aristeia.com/ http://cpp.training/ Slide 572
Efficiency Summary
std::shared_ptr<Widget> sp1{new Widget{args}}; // 2 allocs; CB
// has ptr to
// Widget
auto sp2(std::make_shared<Widget>(args)); // 1 alloc; CB
// has no ptr to
// Widget
// (if WKWYL used)
Scott Meyers, Software Development Consultant Kalb for NVIDIA Copyrighted material, all rights reserved.
http://www.aristeia.com/ http://cpp.training/ Slide 573
Scott Meyers, Software Development Consultant Kalb for NVIDIA Copyrighted material,
http://www.aristeia.com/ http://cpp.training/ all rights reserved.
Topics From Effective C++ Programming
Scott Meyers, Software Development Consultant Kalb for NVIDIA Copyrighted material, all rights reserved.
http://www.aristeia.com/ http://cpp.training/ Slide 574
Staying DRY
Only std::make_shared and std::make_unique adhere to DRY:
§ DRY = “Don’t Repeat Yourself.”
std::shared_ptr<Widget> sp1{new Widget{args}}; // !DRY
auto sp2(std::make_shared<Widget>(args)); // DRY
Scott Meyers, Software Development Consultant Kalb for NVIDIA Copyrighted material, all rights reserved.
http://www.aristeia.com/ http://cpp.training/ Slide 575
Scott Meyers, Software Development Consultant Kalb for NVIDIA Copyrighted material,
http://www.aristeia.com/ http://cpp.training/ all rights reserved.
Topics From Effective C++ Programming
std::allocate_shared
Like std::make_shared, but permits use of custom allocator:
CustomAllocator ca;
…
auto pw(std::allocate_shared<Widget>(ca, args));
Scott Meyers, Software Development Consultant Kalb for NVIDIA Copyrighted material, all rights reserved.
http://www.aristeia.com/ http://cpp.training/ Slide 576
Custom Deleters
No custom deleters with std::make_shared/std::allocate_shared.
Widget* makeWidget(params); // factory function
void reclaimWidget(Widget*); // disposal function
std::shared_ptr<Widget> pw1{makeWidget(args),
reclaimWidget}; // custom deleter
auto pw2(
std::make_shared<Widget>(makeWidget(args),
reclaimWidget)); // interpreted as
// Widget ctor arg!
Same restriction applies to std::make_unique.
Need for custom deleter ⇒ can’t use std::make_shared,
std::allocate_shared, std::make_unique.
Scott Meyers, Software Development Consultant Kalb for NVIDIA Copyrighted material, all rights reserved.
http://www.aristeia.com/ http://cpp.training/ Slide 577
Scott Meyers, Software Development Consultant Kalb for NVIDIA Copyrighted material,
http://www.aristeia.com/ http://cpp.training/ all rights reserved.
Topics From Effective C++ Programming
Scott Meyers, Software Development Consultant Kalb for NVIDIA Copyrighted material, all rights reserved.
http://www.aristeia.com/ http://cpp.training/ Slide 578
Scott Meyers, Software Development Consultant Kalb for NVIDIA Copyrighted material, all rights reserved.
http://www.aristeia.com/ http://cpp.training/ Slide 579
Scott Meyers, Software Development Consultant Kalb for NVIDIA Copyrighted material,
http://www.aristeia.com/ http://cpp.training/ all rights reserved.
Topics From Effective C++ Programming
… // 0 std::shared_ptrs exist,
// ≥ 1 std::weak_ptrs exist
CB
0
std::weak_ptrs WC > 0
Scott Meyers, Software Development Consultant Kalb for NVIDIA Copyrighted material, all rights reserved.
http://www.aristeia.com/ http://cpp.training/ Slide 580
… // 0 std::shared_ptrs exist,
// ≥ 1 std::weak_ptrs exist
CB
0
std::weak_ptrs WC > 0
Scott Meyers, Software Development Consultant Kalb for NVIDIA Copyrighted material, all rights reserved.
http://www.aristeia.com/ http://cpp.training/ Slide 581
Scott Meyers, Software Development Consultant Kalb for NVIDIA Copyrighted material,
http://www.aristeia.com/ http://cpp.training/ all rights reserved.
Topics From Effective C++ Programming
Guideline
Use std::make_shared and std::make_unique whenever possible.
Scott Meyers, Software Development Consultant Kalb for NVIDIA Copyrighted material, all rights reserved.
http://www.aristeia.com/ http://cpp.training/ Slide 583
Scott Meyers, Software Development Consultant Kalb for NVIDIA Copyrighted material,
http://www.aristeia.com/ http://cpp.training/ all rights reserved.
Topics From Effective C++ Programming
Efficiency
Scott Meyers, Software Development Consultant Kalb for NVIDIA Copyrighted material, all rights reserved.
http://www.aristeia.com/ http://cpp.training/ Slide 584
Efficiency Overview
The 80-20 Rule
Efficiency and the language C++:
§ Eliminating unnecessary calls to constructors and destructors
Efficiency and C++’s standard library:
§ Consider Emplacement Instead of Insertion
Scott Meyers, Software Development Consultant Kalb for NVIDIA Copyrighted material, all rights reserved.
http://www.aristeia.com/ http://cpp.training/ Slide 585
Scott Meyers, Software Development Consultant Kalb for NVIDIA Copyrighted material,
http://www.aristeia.com/ http://cpp.training/ all rights reserved.
Topics From Effective C++ Programming
Caveat
Scott Meyers, Software Development Consultant Kalb for NVIDIA Copyrighted material, all rights reserved.
http://www.aristeia.com/ http://cpp.training/ Slide 586
Scott Meyers, Software Development Consultant Kalb for NVIDIA Copyrighted material, all rights reserved.
http://www.aristeia.com/ http://cpp.training/ Slide 587
Scott Meyers, Software Development Consultant Kalb for NVIDIA Copyrighted material,
http://www.aristeia.com/ http://cpp.training/ all rights reserved.
Topics From Effective C++ Programming
Scott Meyers, Software Development Consultant Kalb for NVIDIA Copyrighted material, all rights reserved.
http://www.aristeia.com/ http://cpp.training/ Slide 588
Scott Meyers, Software Development Consultant Kalb for NVIDIA Copyrighted material, all rights reserved.
http://www.aristeia.com/ http://cpp.training/ Slide 589
Scott Meyers, Software Development Consultant Kalb for NVIDIA Copyrighted material,
http://www.aristeia.com/ http://cpp.training/ all rights reserved.
Topics From Effective C++ Programming
Examples
#include <string>
// struct string { // string acts as if it were
// string();
// string(char const*);
// string(string const& rhs);
// ...
// };
using namespace std;
string s1{"Hello”}; // 1 ctor call
string s2{s1}; // 1 ctor call
string s3 = "Hello"; // 1 or 2 ctor calls
string sa1[10]; // 10 ctor calls
string sa2[ ] // 3 or 6 ctor calls
{ string{"One”}, string{"Two”}, string{"Three”} };
Destructors will be called when these objects go out of scope.
Scott Meyers, Software Development Consultant Kalb for NVIDIA Copyrighted material, all rights reserved.
http://www.aristeia.com/ http://cpp.training/ Slide 590
Examples
std::string interleave(std::string str1, std::string str2);
std::cout << interleave(s1, "Hello"); // at least 3 ctor calls
Again, destructors will be called when these objects go away.
Scott Meyers, Software Development Consultant Kalb for NVIDIA Copyrighted material, all rights reserved.
http://www.aristeia.com/ http://cpp.training/ Slide 591
Scott Meyers, Software Development Consultant Kalb for NVIDIA Copyrighted material,
http://www.aristeia.com/ http://cpp.training/ all rights reserved.
Topics From Effective C++ Programming
Constructors, Destructors,
Inheritance, and Composition
Inheritance results in implicit calls:
§ Base class constructors/destructors are called for derived class objects
So does composition:
§ Data members are initialized via constructors and destroyed via
destructors
Scott Meyers, Software Development Consultant Kalb for NVIDIA Copyrighted material, all rights reserved.
http://www.aristeia.com/ http://cpp.training/ Slide 592
Example
struct Person {
Person(std::string const& who, std::string const& where);
...
private:
std::string name;
std::string address;
};
struct Student: Person {
Student(std::string const& who, std::string const& where);
...
private:
std::string idNumber;
};
std::string name{"Chris”};
std::string location{"Bermuda”};
int main() {
Student s(name, location); // 5 ctors called
} // 5 dtors called
Moral: construction and destruction of objects can be very expensive!
Scott Meyers, Software Development Consultant Kalb for NVIDIA Copyrighted material, all rights reserved.
http://www.aristeia.com/ http://cpp.training/ Slide 593
Scott Meyers, Software Development Consultant Kalb for NVIDIA Copyrighted material,
http://www.aristeia.com/ http://cpp.training/ all rights reserved.
Topics From Effective C++ Programming
template<class T>
bool operator!=(T const& lhs, T const& rhs) { return !(lhs == rhs); }
Æ Built-in types are an exception; pass-by-value is okay for them:
std::vector<Widget>
makeClones(Widget const& w, // pass by ref
int numClones); // pass by value
Æ Another exception: things passed by value in the STL, e.g., iterators
and function objects
Scott Meyers, Software Development Consultant Kalb for NVIDIA Copyrighted material, all rights reserved.
http://www.aristeia.com/ http://cpp.training/ Slide 594
Scott Meyers, Software Development Consultant Kalb for NVIDIA Copyrighted material, all rights reserved.
http://www.aristeia.com/ http://cpp.training/ Slide 595
Scott Meyers, Software Development Consultant Kalb for NVIDIA Copyrighted material,
http://www.aristeia.com/ http://cpp.training/ all rights reserved.
Topics From Effective C++ Programming
Scott Meyers, Software Development Consultant Kalb for NVIDIA Copyrighted material, all rights reserved.
http://www.aristeia.com/ http://cpp.training/ Slide 596
Scott Meyers, Software Development Consultant Kalb for NVIDIA Copyrighted material, all rights reserved.
http://www.aristeia.com/ http://cpp.training/ Slide 597
Scott Meyers, Software Development Consultant Kalb for NVIDIA Copyrighted material,
http://www.aristeia.com/ http://cpp.training/ all rights reserved.
Topics From Effective C++ Programming
Scott Meyers, Software Development Consultant Kalb for NVIDIA Copyrighted material, all rights reserved.
http://www.aristeia.com/ http://cpp.training/ Slide 598
Scott Meyers, Software Development Consultant Kalb for NVIDIA Copyrighted material, all rights reserved.
http://www.aristeia.com/ http://cpp.training/ Slide 599
Scott Meyers, Software Development Consultant Kalb for NVIDIA Copyrighted material,
http://www.aristeia.com/ http://cpp.training/ all rights reserved.
Topics From Effective C++ Programming
Scott Meyers, Software Development Consultant Kalb for NVIDIA Copyrighted material, all rights reserved.
http://www.aristeia.com/ http://cpp.training/ Slide 600
Scott Meyers, Software Development Consultant Kalb for NVIDIA Copyrighted material, all rights reserved.
http://www.aristeia.com/ http://cpp.training/ Slide 601
Scott Meyers, Software Development Consultant Kalb for NVIDIA Copyrighted material,
http://www.aristeia.com/ http://cpp.training/ all rights reserved.
Topics From Effective C++ Programming
Scott Meyers, Software Development Consultant Kalb for NVIDIA Copyrighted material, all rights reserved.
http://www.aristeia.com/ http://cpp.training/ Slide 602
Scott Meyers, Software Development Consultant Kalb for NVIDIA Copyrighted material, all rights reserved.
http://www.aristeia.com/ http://cpp.training/ Slide 603
Scott Meyers, Software Development Consultant Kalb for NVIDIA Copyrighted material,
http://www.aristeia.com/ http://cpp.training/ all rights reserved.
Topics From Effective C++ Programming
Scott Meyers, Software Development Consultant Kalb for NVIDIA Copyrighted material, all rights reserved.
http://www.aristeia.com/ http://cpp.training/ Slide 604
Scott Meyers, Software Development Consultant Kalb for NVIDIA Copyrighted material, all rights reserved.
http://www.aristeia.com/ http://cpp.training/ Slide 605
Scott Meyers, Software Development Consultant Kalb for NVIDIA Copyrighted material,
http://www.aristeia.com/ http://cpp.training/ all rights reserved.
Topics From Effective C++ Programming
Scott Meyers, Software Development Consultant Kalb for NVIDIA Copyrighted material, all rights reserved.
http://www.aristeia.com/ http://cpp.training/ Slide 606
Scott Meyers, Software Development Consultant Kalb for NVIDIA Copyrighted material, all rights reserved.
http://www.aristeia.com/ http://cpp.training/ Slide 607
Scott Meyers, Software Development Consultant Kalb for NVIDIA Copyrighted material,
http://www.aristeia.com/ http://cpp.training/ all rights reserved.
Topics From Effective C++ Programming
Scott Meyers, Software Development Consultant Kalb for NVIDIA Copyrighted material, all rights reserved.
http://www.aristeia.com/ http://cpp.training/ Slide 608
Summary
Performance:
§ Emplacement can reduce number of constructions/destructions.
§ In theory, emplacement never costs more than insertion.
§ In practice, emplacement often does.
§ Emplacement most likely a win when:
Æ Value being added is constructed into the container, not assigned.
Æ Argument(s) passed are different from T (for Container<T>).
Æ Value to be added unlikely to be rejected as a duplicate.
Safety:
§ Insertion “respects” explicit constructors, emplacement doesn’t.
Scott Meyers, Software Development Consultant Kalb for NVIDIA Copyrighted material, all rights reserved.
http://www.aristeia.com/ http://cpp.training/ Slide 609
Scott Meyers, Software Development Consultant Kalb for NVIDIA Copyrighted material,
http://www.aristeia.com/ http://cpp.training/ all rights reserved.
Topics From Effective C++ Programming
Guideline
Consider emplacement instead of insertion.
Summary: Efficiency
§ Use the 80-20 rule to focus your efforts.
§ Avoid unnecessary temporaries.
§ Consider emplacement where it is likely to be more efficient than insertion.
Scott Meyers, Software Development Consultant Kalb for NVIDIA Copyrighted material, all rights reserved.
http://www.aristeia.com/ http://cpp.training/ Slide 611
Scott Meyers, Software Development Consultant Kalb for NVIDIA Copyrighted material,
http://www.aristeia.com/ http://cpp.training/ all rights reserved.