c++ in the 21st century

60
C++ in the 21 st Century [email protected] September 2013 For Internal Presentations Only, Not For External Distribution.

Upload: bittorrentinc

Post on 01-Jul-2015

316 views

Category:

Technology


0 download

DESCRIPTION

BitTorrent Chief Architect Arvid Norberg Talks C++ in the 21st Century Learn more: http://blog.bittorrent.com/tag/tech-talks/

TRANSCRIPT

Page 1: C++ in the 21st Century

C++ in the 21st Century [email protected]

September 2013

For Internal Presentations Only, Not For External Distribution.

Page 2: C++ in the 21st Century

For Internal Presentation Purposes Only, Not For External Distribution .

BitTorrent, Inc. | C++ in the 21st Century

C++11

•  for loops • automatic type deduction •  lambda functions • override specifier • smart pointers • error_code • chrono

Page 3: C++ in the 21st Century

For Internal Presentation Purposes Only, Not For External Distribution .

BitTorrent, Inc. | C++ in the 21st Century

•  for loops •  automatic type deduction •  lambda functions •  override specifier •  smart pointers •  error_code •  chrono library features

core language features

C++11

Page 4: C++ in the 21st Century

For Loops

Page 5: C++ in the 21st Century

For Internal Presentation Purposes Only, Not For External Distribution .

BitTorrent, Inc. | C++ in the 21st Century

for (std::vector<int>::iterator i = v.begin()!, end(v.end()); i != end; ++i) {!

print(*i);!}!

int v[] = {1, 3, 3, 7};!for (int i = 0; i < sizeof(v)/sizeof(v[0]); ++i) {!

print(v[i]);!}!

C++98

Page 6: C++ in the 21st Century

For Internal Presentation Purposes Only, Not For External Distribution .

BitTorrent, Inc. | C++ in the 21st Century

for (int a : v) {!print(a);!}!

C++11 For

Page 7: C++ in the 21st Century

For Internal Presentation Purposes Only, Not For External Distribution .

BitTorrent, Inc. | C++ in the 21st Century

for (auto i = begin(v), _end(end(v));! i != _end; ++i) {! int a = *i;!print(a);!}!

Conceptually expands to something like this:

C++11 For

Page 8: C++ in the 21st Century

For Internal Presentation Purposes Only, Not For External Distribution .

BitTorrent, Inc. | C++ in the 21st Century

Conceptually expands to something like this:

argument dependent lookup, to support user defined types

for (auto i = begin(v), _end(end(v));! i != _end; ++i) {! int a = *i;!print(a);!}!

C++11 For

Page 9: C++ in the 21st Century

For Internal Presentation Purposes Only, Not For External Distribution .

BitTorrent, Inc. | C++ in the 21st Century

template<class A, int N>!A* begin(A a[N]) { return &a[0]; }!!template<class A, int N>!A* end(A a[N]) { return &a[N]; }!!

This is why it also works for C-arrays

C++11 For

Page 10: C++ in the 21st Century

For Internal Presentation Purposes Only, Not For External Distribution .

BitTorrent, Inc. | C++ in the 21st Century

for loops automatic type deduction

lambda functions override specifier

smart pointers error_code

chrono

C++11 For

Page 11: C++ in the 21st Century

Automatic Type Deduction

Page 12: C++ in the 21st Century

For Internal Presentation Purposes Only, Not For External Distribution .

BitTorrent, Inc. | C++ in the 21st Century

New use of keyword auto - automatically deduces the type of a variable declaration. New keyword decltype() - deduces the type of an expression. This can be used in type expressions other than variable declarations, such as template arguments.

C++11 Auto

Page 13: C++ in the 21st Century

For Internal Presentation Purposes Only, Not For External Distribution .

BitTorrent, Inc. | C++ in the 21st Century

C++11 Declytype

std::vector<decltype(f())> vals;!std::generate_n(std::back_inserter(vals), 10, &f);!

Page 14: C++ in the 21st Century

For Internal Presentation Purposes Only, Not For External Distribution .

BitTorrent, Inc. | C++ in the 21st Century

std::vector<decltype(f())> vals;!std::generate_n(std::back_inserter(vals), 10, &f);!

f() is not evaluated, similar to sizeof(). decltype expression is a type

C++11 Declytype

Page 15: C++ in the 21st Century

For Internal Presentation Purposes Only, Not For External Distribution .

BitTorrent, Inc. | C++ in the 21st Century

std::map<std::string, int> m;!!std::map<std::string, int>::iterator i =!

m.find(“foobar”);!if (i == m.end()) return;!

C++98 Auto

Page 16: C++ in the 21st Century

For Internal Presentation Purposes Only, Not For External Distribution .

BitTorrent, Inc. | C++ in the 21st Century

std::map<std::string, int> m;!!auto i = m.find(“foobar”);!if (i == m.end()) return;!

C++11 Auto

Page 17: C++ in the 21st Century

For Internal Presentation Purposes Only, Not For External Distribution .

BitTorrent, Inc. | C++ in the 21st Century

std::map<std::string, int> m;!!auto i = m.find(“foobar”);!if (i == m.end()) return;!

Type deduced from return type of function call

C++11 Auto

Page 18: C++ in the 21st Century

For Internal Presentation Purposes Only, Not For External Distribution .

BitTorrent, Inc. | C++ in the 21st Century

std::map<std::string, int> m;!!auto i = m.find(“foobar”);!if (i == m.end()) return;!

conceptually: decltype(m.find(“foobar”)) i = ...

C++11 Auto

Page 19: C++ in the 21st Century

For Internal Presentation Purposes Only, Not For External Distribution .

BitTorrent, Inc. | C++ in the 21st Century

•  for loops • automatic type deduction •  lambda functions • override specifier • smart pointers • error_code • chrono

C++11 Auto

Page 20: C++ in the 21st Century

Function Objects

Page 21: C++ in the 21st Century

For Internal Presentation Purposes Only, Not For External Distribution .

BitTorrent, Inc. | C++ in the 21st Century

C++98 Function objects

struct is_divisible_by {! is_divisible_by(int denom): d(denom) {}! bool operator()(int n) const! { return n % d == 0; }! int d;!}!!std::vector<int>::iterator i =!std::find_if(v.begin()!, v.end(), is_divisible_by(x));!

Page 22: C++ in the 21st Century

For Internal Presentation Purposes Only, Not For External Distribution .

BitTorrent, Inc. | C++ in the 21st Century

bool is_divisible_by()(int n, int d)!{ return n % d == 0; }!!std::vector<int>::iterator i =! std::find_if(v.begin()!, v.end(), std::bind(&is_divisible_by, _1, x));!

C++03 Function objects

Page 23: C++ in the 21st Century

For Internal Presentation Purposes Only, Not For External Distribution .

BitTorrent, Inc. | C++ in the 21st Century

bool is_divisible_by()(int n, int d)!{ return n % d == 0; }!!std::vector<int>::iterator i =! std::find_if(v.begin()!, v.end(), std::bind(&is_divisible_by, _1, x));!

Partially applied function

C++03 Function objects

Page 24: C++ in the 21st Century

For Internal Presentation Purposes Only, Not For External Distribution .

BitTorrent, Inc. | C++ in the 21st Century

C++11 Function objects

auto i = std::find_if(v.begin()!, v.end(), [=](int n) { return n % x == 0; });!

Page 25: C++ in the 21st Century

For Internal Presentation Purposes Only, Not For External Distribution .

BitTorrent, Inc. | C++ in the 21st Century

C++11 Function objects

• New syntax for lambda functions. • Expressions that implicitly create function objects

that captures referenced values from the scope. • Values can be captured by value, by reference or both

Page 26: C++ in the 21st Century

For Internal Presentation Purposes Only, Not For External Distribution .

BitTorrent, Inc. | C++ in the 21st Century

std::vector<int> v = {1,2,3,4,5,6,7};!int x = 2;!auto i = std::find_if(v.begin()!, v.end(), [=](int n) { return n % x == 0; });!

copy x into lambda scope

capture expression (copy)

C++11 Function objects

Page 27: C++ in the 21st Century

For Internal Presentation Purposes Only, Not For External Distribution .

BitTorrent, Inc. | C++ in the 21st Century

[=](int n) { return n % x == 0; });!copy captured variables from context !![&](int n) { return n % x == 0; });!capture context variables by reference (lvalues) !![&x](int n) { return n % x == y; });!explicitly capture x by reference, anything else is captured by copy

C++11 Function objects

Page 28: C++ in the 21st Century

For Internal Presentation Purposes Only, Not For External Distribution .

BitTorrent, Inc. | C++ in the 21st Century

auto i = std::transform(v.begin(), v.end()!, [=](double n) -> double!

{ if (n < 0.1) return 0; else return n; });!!!If the compiler fails to deduce return type for the lambda, it can be specified with the -> syntax.

C++11 Function objects

Page 29: C++ in the 21st Century

For Internal Presentation Purposes Only, Not For External Distribution .

BitTorrent, Inc. | C++ in the 21st Century

•  for loops • automatic type deduction •  lambda functions • override specifier • smart pointers • error_code • chrono

C++11

Page 30: C++ in the 21st Century

Override Specifier

Page 31: C++ in the 21st Century

For Internal Presentation Purposes Only, Not For External Distribution .

BitTorrent, Inc. | C++ in the 21st Century

C++11 Override specifier

struct shape { virtual void draw(); };!!struct rectangle : shape!{ virtual void draw() const; };!

Page 32: C++ in the 21st Century

For Internal Presentation Purposes Only, Not For External Distribution .

BitTorrent, Inc. | C++ in the 21st Century

struct shape { virtual void draw(); };!!struct rectangle : shape!{ virtual void draw() const; };!

Does not override shape’s draw!

C++11 Override specifier

Page 33: C++ in the 21st Century

For Internal Presentation Purposes Only, Not For External Distribution .

BitTorrent, Inc. | C++ in the 21st Century

struct shape { virtual void draw(); };!!struct rectangle : shape!{ virtual void draw() const override; };!

tell the compiler that we want this to override a function from the base class

Error: Has a different signature from ‘shape::draw’!

C++11 Final specifier

Page 34: C++ in the 21st Century

For Internal Presentation Purposes Only, Not For External Distribution .

BitTorrent, Inc. | C++ in the 21st Century

struct shape : entity!{ virtual void move(); };!!struct rectangle : shape!{ virtual void move(); };!

C++11 Final specifier

Page 35: C++ in the 21st Century

For Internal Presentation Purposes Only, Not For External Distribution .

BitTorrent, Inc. | C++ in the 21st Century

struct shape : entity!{ virtual void move() final; };!!struct rectangle : shape!{ virtual void move(); };!

not allowed to be overridden!

Error: move cannot be overridden as it's final in ‘shape’!

C++11 Final specifier

Page 36: C++ in the 21st Century

For Internal Presentation Purposes Only, Not For External Distribution .

BitTorrent, Inc. | C++ in the 21st Century

•  for loops • automatic type deduction •  lambda functions • override specifier • smart pointers • error_code • chrono

C++11

Page 37: C++ in the 21st Century

Smart Pointers

Page 38: C++ in the 21st Century

For Internal Presentation Purposes Only, Not For External Distribution .

BitTorrent, Inc. | C++ in the 21st Century

template <class T> unique_ptr<T>;!delete object when pointer goes out of scope. pointer is not copyable (but movable).

replaces the somewhat broken std::auto_ptr<T>. Useful for returning heap allocated objects and constructing temporary heap objects.

C++11 Smart pointers

Page 39: C++ in the 21st Century

For Internal Presentation Purposes Only, Not For External Distribution .

BitTorrent, Inc. | C++ in the 21st Century

std::unique_ptr<A> a = new A;!!a->foo();!a->bar();!!// a is deleted at the end of the scope // typically one would just create A // on the stack in this case

C++11 Smart pointers

Page 40: C++ in the 21st Century

For Internal Presentation Purposes Only, Not For External Distribution .

BitTorrent, Inc. | C++ in the 21st Century

std::unique_ptr<shape> get_new_shape() {!switch (std::rand() % 2) {!case 0: return new rectangle();!case 1: return new circle();!

}!}!!users of this function do not need to think about object ownership or lifetime.

C++11 Smart pointers

Page 41: C++ in the 21st Century

For Internal Presentation Purposes Only, Not For External Distribution .

BitTorrent, Inc. | C++ in the 21st Century

template <class T> shared_ptr<T>;!delete object when last pointer goes out of scope. pointer is copyable and reference counting.

template <class T> weak_ptr<T>;!

non reference counting pointer to object held by shared_ptr.

template <class T, ...A>!shared_ptr<T> make_shared(A... args);!

constructs an instance of T held by a shared_ptr.

C++11 Smart pointers

Page 42: C++ in the 21st Century

For Internal Presentation Purposes Only, Not For External Distribution .

BitTorrent, Inc. | C++ in the 21st Century

shared_ptr<socket> c = make_shared<socket>();!c->connect(/* ... */);!c->async_read([=] (size_t, error_code const&)!{ c->async_write(...); });! // as long as the operation is outstanding, // the connection object is kept alive

C++11 Smart pointers

Page 43: C++ in the 21st Century

For Internal Presentation Purposes Only, Not For External Distribution .

BitTorrent, Inc. | C++ in the 21st Century

•  for loops • automatic type deduction •  lambda functions • override specifier • smart pointers • error_code • chrono

C++11

Page 44: C++ in the 21st Century

Error_code

Page 45: C++ in the 21st Century

For Internal Presentation Purposes Only, Not For External Distribution .

BitTorrent, Inc. | C++ in the 21st Century

Using an integer for errors: + easy to programmatically handle errors + error message can be localized - which domain does the error belong to (posix, http, openssl, windows, ...) - not easily interpreted by human (especially with domain unknown)

C++11 Error_code

Page 46: C++ in the 21st Century

For Internal Presentation Purposes Only, Not For External Distribution .

BitTorrent, Inc. | C++ in the 21st Century

Using a string for errors: + easily interpreted by humans - hard to programmatically handle errors - which domain does the error belong to? (not clear unless the string is verbose) - essentially impossible to localize

C++11 Error_code

Page 47: C++ in the 21st Century

For Internal Presentation Purposes Only, Not For External Distribution .

BitTorrent, Inc. | C++ in the 21st Century

error_code represents an error and solves all of those problems. error_code has an integral error_value, indicating the error as well as a category, indicating the domain of the error_value. category is an abstract base class implementing error_value -> human error message. category is critical for compossibility.

C++11 Error_code

Page 48: C++ in the 21st Century

For Internal Presentation Purposes Only, Not For External Distribution .

BitTorrent, Inc. | C++ in the 21st Century

tcp::socket s;!error_code ec;!s.connect(/* ... */, ec);!if (ec) {!printf(“failed to connect: [%s:%d] %s\n”!

, ec.category().name()!, ec.value()!, ec.message().c_str());!

exit(1);!}!!!

C++11 Error_code

Page 49: C++ in the 21st Century

For Internal Presentation Purposes Only, Not For External Distribution .

BitTorrent, Inc. | C++ in the 21st Century

using an error_code for errors: !+ easily interpreted by humans!+ easy to programmatically handle errors!+ clear which domain the error belongs to!+ possible to localize!

C++11 Error_code

Page 50: C++ in the 21st Century

For Internal Presentation Purposes Only, Not For External Distribution .

BitTorrent, Inc. | C++ in the 21st Century

•  for loops • automatic type deduction •  lambda functions • override specifier • smart pointers • error_code • chrono

C++11

Page 51: C++ in the 21st Century

Chrono C++ timer library

Page 52: C++ in the 21st Century

For Internal Presentation Purposes Only, Not For External Distribution .

BitTorrent, Inc. | C++ in the 21st Century

Nanosecond resolution and millennia range of timestamps? (both do not fit in 64 bits) Separate functions for second, millisecond, microsecond resolution clocks? Floating point timestamps? Type safety of timestamps? (pass in microseconds to a sleep that takes milliseconds, then wait...)

C++11 Chrono

Page 53: C++ in the 21st Century

For Internal Presentation Purposes Only, Not For External Distribution .

BitTorrent, Inc. | C++ in the 21st Century

in C++98 and POSIX, we have the following timers: std::clock() / CLOCKS_PER_SEC time() clock_gettime() / clock_getres() gettimeofday()

C++98 Chrono

Page 54: C++ in the 21st Century

For Internal Presentation Purposes Only, Not For External Distribution .

BitTorrent, Inc. | C++ in the 21st Century

in C++98 and POSIX, we have the following timers: std::clock() / CLOCKS_PER_SEC time() clock_gettime() / clock_getres() gettimeofday()

nanosecond resolution, but is not monotonic (daylight

savings, ntpd adjustments)

high resolution and monotonic. not supported on

windows and some POSIX

very low resolution

second resolution, not monotonic

C++98 Chrono

Page 55: C++ in the 21st Century

For Internal Presentation Purposes Only, Not For External Distribution .

BitTorrent, Inc. | C++ in the 21st Century

Chrono introduces an abstract concept of a clock, with its own epoch and its own resolution. time_point - a point in time, relative to the epoch time_duration - a delta between two time points,

a certain number of ticks.

C++11 Chrono

Page 56: C++ in the 21st Century

For Internal Presentation Purposes Only, Not For External Distribution .

BitTorrent, Inc. | C++ in the 21st Century

To query the current time: clock::time_point timestamp = clock::now(); C++11 provides 3 standard clocks: std::chrono::system_clock - real-time clock std::chrono::steady_clock - guaranteed to be monotonic std::chrono::high_resolution_clock - system’s highest resolution

C++98 Chrono

Page 57: C++ in the 21st Century

For Internal Presentation Purposes Only, Not For External Distribution .

BitTorrent, Inc. | C++ in the 21st Century

the time_point and time_duration types have their resolution encoded in their types. duration<int,ratio<1,1000000000>> nanoseconds;!duration<int,ratio<1,1000000>> microseconds;!duration<int,ratio<1,1000>> milliseconds;!duration<int,ratio<1,1>> seconds;!duration<int,ratio<60,1>> minutes;!duration<int,ratio<3600,1>> hours;!

C++11 Chrono

Page 58: C++ in the 21st Century

For Internal Presentation Purposes Only, Not For External Distribution .

BitTorrent, Inc. | C++ in the 21st Century

conversion of resolution is automatic, i.e. you have type safety void sleep(milliseconds s);!sleep(seconds(10)); // OK!!

C++11 Chrono

Page 59: C++ in the 21st Century

For Internal Presentation Purposes Only, Not For External Distribution .

BitTorrent, Inc. | C++ in the 21st Century

duration<int,ratio<1,3>> d1(1); // 1 tick of 1/3 second!duration<int,ratio<1,5>> d2(1); // 1 tick of 1/5 second!!auto d = d1 + d2;!// yields 8 ticks of 1/15th seconds!// duration<int,ratio<1,15>> d(8);!!d2 < d1 // yields true!

C++11 Chrono

Page 60: C++ in the 21st Century

For Internal Presentation Purposes Only, Not For External Distribution .

BitTorrent, Inc. | C++ in the 21st Century

range-for: for (int a : v) { printf(“%d\n”, a); }!keywords: auto decltype override final!lambda: [=](int x) { return x % n == 0; }!smart ptrs: shared_ptr<> make_shared<> unique_ptr<>!types: error_code, time_point, time_duration!

Thank You

C++11