Dave Abrahams, BoostPro Computing
He is a founding member of Boost.org and an active participant in the ISO C++ standards committee. His broad range of experience in the computer industry includes shrink-wrap software development, embedded systems design and natural language processing. He has authored eight Boost libraries and has made contributions to numerous others. Dave made his mark on C++ standardization by developing a conceptual framework for understanding exception-safety and applying it to the C++ standard library. He created the first exception-safe standard library implementation and, with Greg Colvin, drafted the proposals that eventually became the standard library’s exception safety guarantees.
Presentation topic:
C++11 (formerly known as C++0x) is the new C++ language standard. Dave Abrahams, BoostPro Computing.
Key points:
The ISO C++ standardization committee has just unanimously approved its final draft international standard, and it's chock full of new features. Though a few of the features have been available for years, some are brand new, and nobody really knows what it's like to program in this new C++ language. As with C++03, Boost.org is expected to take a leading role in exploiting C++11. In this talk, I'll give an overview of the most important new developments.
Boost Fertility New Invention Ups Success Rates.pdf
C++11 (formerly known as C++0x) is the new C++ language standard. Dave Abrahams, BoostPro Computing
1. C++ 2011
Highlights from the New International Standard
1
Monday, September 19, 2011
2. Intro
• Who am I
• Who are you?
• Why We’re Here
2
Monday, September 19, 2011
3. C++11 Goals
• Make C++ a better language for systems
programming
• Make C++ a better language for writing libraries
• Make C++ more teachable and learnable
• Maintain backward compatibility
3
Monday, September 19, 2011
4. C++11 At a Glance
• General Core Language Features
concurrency, move semantics, auto, range-based for, lambdas…
• Library Features
containers, regular expressions, smart pointers, new algorithms…
• Features for writing classes
constructor delegation, override/final, =default/=delete…
• Crazy Template Stuff
Variadic templates, template aliases, decltype, perfect forwarding, …
4
Monday, September 19, 2011
6. Type Deduction
void print_3x(vector<float> const& v)
{
for ( vector<float>::const_iterator p = v.begin();
p != v.end(); p++ )
{
std::cout << *p * 3 << " ";
}
}
6
Monday, September 19, 2011
7. Type Deduction
void print_3x(vector<float> const& v)
{
for ( vector<float>::const_iterator p = v.begin();
p != v.end(); p++ )
{
std::cout << *p * 3 << " ";
}
}
6
Monday, September 19, 2011
8. Type Deduction
void print_3x(vector<float> const& v)
{
for ( auto p = v.begin();
p != v.end(); p++ )
{
std::cout << *p * 3 << " ";
}
}
7
Monday, September 19, 2011
9. Type Deduction
void print_3x(vector<float> const& v)
{
for ( auto p = v.begin(); p != v.end(); p++ )
{
std::cout << *p * 3 << " ";
}
}
8
Monday, September 19, 2011
10. Type Deduction
auto a = 3; int
const auto b = 3.14; const double
auto const& c = 42; int const&
auto d = "foobar"; char const*
auto& e = "baz" char const(&)[4]
extern std::list<Foo> l;
auto p = l.begin(); std::list<Foo>::iterator
auto& x = l.front(); std::list<Foo>::value_type&
auto& y = any-expression-here;
9
Monday, September 19, 2011
11. Type Deduction
void print_3x(vector<float> const& v)
{
for ( auto p = v.begin(); p != v.end(); p++ )
{
std::cout << *p * 3 << " ";
}
}
10
Monday, September 19, 2011
12. Range-based for loop
void print_3x(vector<float> const& v)
{
for ( auto p = v.begin(); p != v.end(); p++ )
{
std::cout << *p * 3 << " ";
}
}
11
Monday, September 19, 2011
13. Range-based for loop
void print_3x(vector<float> const& v)
{
for ( float a: v )
{
std::cout << a * 3 << " ";
}
}
12
Monday, September 19, 2011
14. Range-based for loop
void print_3x(vector<float> const& v)
Range
{
for ( float a: v )
{
std::cout << a * 3 << " ";
}
}
12
Monday, September 19, 2011
15. Range-based for loop
void print_3x(vector<float> const& v)
Loop variable Range
{
for ( float a: v )
{
std::cout << a * 3 << " ";
}
}
12
Monday, September 19, 2011
16. Range-based for loop
auto in C++11
void print_3x(vector<float> const& v)
{
for ( auto a: v )
{
std::cout << a * 3 << " ";
}
}
13
Monday, September 19, 2011
17. Range-based for loop
template <class Range>
void print_3x(Range const& v)
{
for ( typename Range::value_type a: v )
{
std::cout << a * 3 << " ";
}
}
14
Monday, September 19, 2011
18. Range-based for loop
auto in C++11
template <class Range>
void print_3x(Range const& v)
{
for ( auto a: v )
{
std::cout << a * 3 << " ";
}
}
15
Monday, September 19, 2011
19. Range-based for loop
auto in C++11
void inplace_3x(vector<float>& v)
{
for ( float& a: v )
{
a *= 3;
}
}
16
Monday, September 19, 2011
20. Ranges Everywhere
int rng[3] = { 42, 314, 77 };
for( int var: rng )
{
...
}
17
Monday, September 19, 2011
22. Ranges Everywhere
YourType rng;
for( int var: rng )
{
...
}
19
Monday, September 19, 2011
23. 98
++Range-based for loop
C
void print_3x(vector<float> const& v)
{
BOOST_FOREACH( float a, v )
{
std::cout << a * 3 << " ";
}
}
20
Monday, September 19, 2011
24. 98
++Range-based“for”loop
C
void print_3x(vector<float> const& v)
{
BOOST_FOREACH( float a, v )
{
std::cout << a * 3 << " ";
}
}
20
Monday, September 19, 2011
25. 98
++Range-based“for”loop
C
void print_3x(vector<float> const& v)
{
BOOST_FOREACH( float a, v )
{
std::cout << a * 3 << " ";
}
}
See your friendly neighborhood
Boost C++ Libraries for details
20
Monday, September 19, 2011
26. Using an Algorithm
void print_3x(vector<float> const& v)
{
std::for_each(
v.begin(), v.end(), );
}
21
Monday, September 19, 2011
27. Using an Algorithm
void print_3x(vector<float> const& v)
{
std::for_each(
v.begin(), v.end(), );
}
21
Monday, September 19, 2011
28. Using an Algorithm
void print_3x(vector<float> const& v)
{
std::for_each(
v.begin(), v.end(), );
}
21
Monday, September 19, 2011
29. Using an Algorithm
static void print_3x_element(float a)
{
std::cout << a * 3 << " ";
}
void print_3x(vector<float> const& v)
{
std::for_each(
v.begin(), v.end(), );
}
21
Monday, September 19, 2011
30. Using an Algorithm
static void print_3x_element(float a)
{
std::cout << a * 3 << " ";
}
void print_3x(vector<float> const& v)
{
std::for_each(
v.begin(), v.end(), print_3x_element);
}
21
Monday, September 19, 2011
31. Using an Algorithm
static void print_3x_element(float a)
{
std::cout << a * 3 << " ";
}
void print_3x(vector<float> const& v)
{
std::for_each(
v.begin(), v.end(), print_3x_element);
}
21
Monday, September 19, 2011
47. Copy Fatigue?
typedef set<string> record;
typedef vector<record> database;
database load_db(string filename);
database db = load_db("huge.db");
db.push_back( create_record() );
• A
27
Monday, September 19, 2011
48. Copy Fatigue?
typedef set<string> record;
typedef vector<record> database;
database load_db(string filename);
database db = load_db("huge.db");
db.push_back( create_record() );
• A B
27
Monday, September 19, 2011
49. Copy Fatigue?
typedef set<string> record;
typedef vector<record> database;
database load_db(string filename);
database db = load_db("huge.db");
db.push_back( create_record() );
• A B C
27
Monday, September 19, 2011
50. Copy Fatigue?
typedef set<string> record;
typedef vector<record> database;
database load_db(string filename);
database db = load_db("huge.db");
db.push_back( create_record() );
• A B C D
27
Monday, September 19, 2011
51. Copy Fatigue?
typedef set<string> record;
typedef vector<record> database;
database load_db(string filename);
database db = load_db("huge.db");
db.push_back( create_record() );
• A B C D
27
Monday, September 19, 2011
52. Copy Fatigue?
typedef set<string> record;
typedef vector<record> database;
database load_db(string filename);
database db = load_db("huge.db");
db.push_back( create_record() );
• A B C D
A
27
Monday, September 19, 2011
53. Copy Fatigue?
typedef set<string> record;
typedef vector<record> database;
database load_db(string filename);
database db = load_db("huge.db");
db.push_back( create_record() );
• A B C D
A B
27
Monday, September 19, 2011
54. Copy Fatigue?
typedef set<string> record;
typedef vector<record> database;
database load_db(string filename);
database db = load_db("huge.db");
db.push_back( create_record() );
• A B C D
A B C
27
Monday, September 19, 2011
55. Copy Fatigue?
typedef set<string> record;
typedef vector<record> database;
database load_db(string filename);
database db = load_db("huge.db");
db.push_back( create_record() );
• A B C D
A B C D
27
Monday, September 19, 2011
56. Copy Fatigue?
typedef set<string> record;
typedef vector<record> database;
database load_db(string filename);
database db = load_db("huge.db");
db.push_back( create_record() );
• A B C D
A B C D
28
Monday, September 19, 2011
57. Copy Fatigue?
typedef set<string> record;
typedef vector<record> database;
database load_db(string filename);
database db = load_db("huge.db");
db.push_back( create_record() );
•
A B C D
28
Monday, September 19, 2011
58. Copy Fatigue?
typedef set<string> record;
typedef vector<record> database;
database load_db(string filename);
database db = load_db("huge.db");
db.push_back( create_record() );
• A B C D
28
Monday, September 19, 2011
59. Copy Fatigue?
typedef set<string> record;
typedef vector<record> database;
database load_db(string filename);
database db = load_db("huge.db");
db.push_back( create_record() );
• A B C D E
28
Monday, September 19, 2011
60. Copy Fatigue?
typedef set<string> record;
typedef vector<record> database;
database load_db(string filename);
database db = load_db("huge.db");
db.push_back( create_record() );
• A B C D E
28
Monday, September 19, 2011
61. Copy Fatigue?
typedef set<string> record;
typedef vector<record> database;
database load_db(string filename); Expensive
database db = load_db("huge.db");
copies are
made just
before
db.push_back( create_record() ); destroying
the source
object
• A B C D E
28
Monday, September 19, 2011
62. Try Moving Instead!
typedef set<string> record;
typedef vector<record> database;
database load_db(string filename);
database db = load_db("huge.db");
db.push_back( create_record() );
• A B C D
29
Monday, September 19, 2011
63. Try Moving Instead!
typedef set<string> record;
typedef vector<record> database;
database load_db(string filename);
database db = load_db("huge.db");
db.push_back( create_record() );
• B C D
A
29
Monday, September 19, 2011
64. Try Moving Instead!
typedef set<string> record;
typedef vector<record> database;
database load_db(string filename);
database db = load_db("huge.db");
db.push_back( create_record() );
• C D
A B
29
Monday, September 19, 2011
65. Try Moving Instead!
typedef set<string> record;
typedef vector<record> database;
database load_db(string filename);
database db = load_db("huge.db");
db.push_back( create_record() );
• D
A B C
29
Monday, September 19, 2011
66. Try Moving Instead!
typedef set<string> record;
typedef vector<record> database;
database load_db(string filename);
database db = load_db("huge.db");
db.push_back( create_record() );
•
A B C D
29
Monday, September 19, 2011
67. Try Moving Instead!
typedef set<string> record;
typedef vector<record> database;
database load_db(string filename);
database db = load_db("huge.db");
db.push_back( create_record() );
•
A B C D
29
Monday, September 19, 2011
68. Try Moving Instead!
typedef set<string> record;
typedef vector<record> database;
database load_db(string filename);
database db = load_db("huge.db");
db.push_back( create_record() );
•
A B C D
30
Monday, September 19, 2011
69. Try Moving Instead!
typedef set<string> record;
typedef vector<record> database;
database load_db(string filename);
database db = load_db("huge.db");
db.push_back( create_record() );
• A B C D
30
Monday, September 19, 2011
70. Try Moving Instead!
typedef set<string> record;
typedef vector<record> database;
database load_db(string filename);
database db = load_db("huge.db");
db.push_back( create_record() );
• A B C D E
30
Monday, September 19, 2011
71. Try Moving Instead!
typedef set<string> record;
typedef vector<record> database;
database load_db(string filename);
database db = load_db("huge.db");
db.push_back( create_record() );
• A B C D E
30
Monday, September 19, 2011
72. Move Mini-HOWTO
Move-enabling an existing class
31
Monday, September 19, 2011
73. Move-Enabling
struct Owner { • X
Owner(const Owner& src)
: p(src.p ? new Resource(*src.p) : 0) {}
Owner& operator=(const Owner& src) {
if (this == &src) return *this;
delete p; p = 0;
if (src.p) p = new Resource(*src.p);
return *this;
}
~Owner() { delete p; }
private:
Resource* p;
};
32
Monday, September 19, 2011
74. Move-Enabling
struct Owner { • X
Owner(const Owner& src)
: p(src.p ? new Resource(*src.p) : 0) {}
Owner& operator=(const Owner& src) {
if (this == &src) return *this;
delete p; p = 0;
if (src.p) p = new Resource(*src.p);
return *this;
}
~Owner() { delete p; }
private:
Resource* p;
};
32
Monday, September 19, 2011
75. Move-Enabling
struct Owner { • X
Owner(const Owner& src)
: p(src.p ? new Resource(*src.p) : 0) {}
Owner& operator=(const Owner& src) {
if (this == &src) return *this;
delete p; p = 0;
if (src.p) p = new Resource(*src.p);
return *this;
}
~Owner() { delete p; }
private:
Resource* p;
};
32
Monday, September 19, 2011
76. Move-Enabling
struct Owner { • X
Owner(const Owner& src)
: p(src.p ? new Resource(*src.p) : 0) {} X
Owner& operator=(const Owner& src) {
if (this == &src) return *this;
delete p; p = 0;
if (src.p) p = new Resource(*src.p);
return *this;
}
~Owner() { delete p; }
private:
Resource* p;
};
32
Monday, September 19, 2011
77. Move-Enabling
struct Owner { • X
Owner(const Owner& src)
: p(src.p ? new Resource(*src.p) : 0) {} X
Owner& operator=(const Owner& src) {
if (this == &src) return *this;
delete p; p = 0;
if (src.p) p = new Resource(*src.p);
return *this;
}
~Owner() { delete p; }
private:
Resource* p;
};
32
Monday, September 19, 2011
78. Move-Enabling
struct Owner { • X
Owner(const Owner& src)
: p(src.p ? new Resource(*src.p) : 0) {} • X
Owner& operator=(const Owner& src) {
if (this == &src) return *this;
delete p; p = 0;
if (src.p) p = new Resource(*src.p);
return *this;
}
~Owner() { delete p; }
private:
Resource* p;
};
32
Monday, September 19, 2011
79. Move-Enabling
struct Owner {
Owner(const Owner& src)
: p(src.p ? new Resource(*src.p) : 0) {}
Owner& operator=(const Owner& src) {
if (this == &src) return *this; • Y
delete p; p = 0;
if (src.p) p = new Resource(*src.p); • Z
return *this;
}
~Owner() { delete p; }
private:
Resource* p;
};
33
Monday, September 19, 2011
80. Move-Enabling
struct Owner {
Owner(const Owner& src)
: p(src.p ? new Resource(*src.p) : 0) {}
Owner& operator=(const Owner& src) {
if (this == &src) return *this; • Y
delete p; p = 0;
if (src.p) p = new Resource(*src.p); • Z
return *this;
}
~Owner() { delete p; }
private:
Resource* p;
};
33
Monday, September 19, 2011
81. Move-Enabling
struct Owner {
Owner(const Owner& src)
: p(src.p ? new Resource(*src.p) : 0) {}
Owner& operator=(const Owner& src) {
if (this == &src) return *this; • Y
delete p; p = 0;
if (src.p) p = new Resource(*src.p); • Z
return *this;
}
~Owner() { delete p; }
private:
Resource* p;
};
33
Monday, September 19, 2011
82. Move-Enabling
struct Owner {
Owner(const Owner& src)
: p(src.p ? new Resource(*src.p) : 0) {}
Owner& operator=(const Owner& src) {
if (this == &src) return *this; • Y
delete p; p = 0;
if (src.p) p = new Resource(*src.p); •
return *this;
}
~Owner() { delete p; }
private:
Resource* p;
};
33
Monday, September 19, 2011
83. Move-Enabling
struct Owner {
Owner(const Owner& src)
: p(src.p ? new Resource(*src.p) : 0) {}
Owner& operator=(const Owner& src) {
if (this == &src) return *this; • Y
delete p; p = 0;
if (src.p) p = new Resource(*src.p); •
return *this;
}
~Owner() { delete p; }
private:
Resource* p;
};
33
Monday, September 19, 2011
84. Move-Enabling
struct Owner {
Owner(const Owner& src)
: p(src.p ? new Resource(*src.p) : 0) {}
Owner& operator=(const Owner& src) {
if (this == &src) return *this; • Y
delete p; p = 0;
if (src.p) p = new Resource(*src.p); •
return *this;
}
~Owner() { delete p; }
private:
Resource* p;
};
33
Monday, September 19, 2011
85. Move-Enabling
struct Owner {
Owner(const Owner& src)
: p(src.p ? new Resource(*src.p) : 0) {}
Owner& operator=(const Owner& src) {
if (this == &src) return *this; • Y
delete p; p = 0;
if (src.p) p = new Resource(*src.p); • Y
return *this;
}
~Owner() { delete p; }
private:
Resource* p;
};
33
Monday, September 19, 2011
86. Move-Enabling
struct Owner {
Owner(const Owner& src)
: p(src.p ? new Resource(*src.p) : 0) {}
Owner& operator=(const Owner& src) {
if (this == &src) return *this; • Y
delete p; p = 0;
if (src.p) p = new Resource(*src.p); • Y
return *this;
}
~Owner() { delete p; }
private:
Resource* p;
};
33
Monday, September 19, 2011
87. New Move Operations
struct Owner {
Owner(const Owner& src)
: p(src.p ? new Resource(*src.p) : 0) {}
Owner& operator=(const Owner& src) {
if (this == &src) return *this;
delete p; p = 0;
if (src.p) p = new Resource(*src.p);
return *this;
}
~Owner() { delete p; }
private:
Resource* p;
};
34
Monday, September 19, 2011
106. Move Semantics
• Automatically accelerates existing code!
• Applied throughout standard library
• Many move-only types in library
• Launches a new era of value semantics
37
Monday, September 19, 2011
110. Classes and OOP
• member initializers
• explict conversion
• override and final
• delegating and inheriting constructors
• defaulted and deleted functions
41
Monday, September 19, 2011