Bjarne Stroustrup - The Essence of C++: With Examples in C++84, C++98, C++11, and C++14

A look at many of the new features in C++ and a couple of old features you may not have known about. With the goal of correctness in mind, we’ll see how to utilize these features to create simple, clear, and beautiful code. Just a little pinch can really spice things up.
Great talk! And, indeed, we _need_ Sean to write a book!
+1 for the book. Great presentation, have to watch it a couple times more to grasp the last bits of it, can't wait!
Definitely he must write down a book with uses cases on applying that wisdom.
Great talk! Looking forward to watching it again once it is online.
When will the video be put online?
yes Great 3 suggestions and the vivid examples, +1 for the book, just can not wait :D
+1 for the book.
The examples were well thought out and consumable by less-experienced C++ developers like me.
+100 for the book
And it would be great to see actual (fresh) ASL code
@dzyashu - I'm working on updating ASL to C++11, cleaning out a lot of overlap with C++11 and newer Boost, and I'll be moving the license shortly to the Boost license to make it easier to incorporate into Boost. Work is currently happening on github at github.com/stlab in the legacy repo (plan is to migrate pieces out as work completes). Progress is slow, but it is moving.
can we have the slide uploaded here ?
@SeanParent - Cool! Can't wait to appreciate. By the way, I understand that it takes huge amount of effort and time to write a book, so may be you or Adobe has (or would create) some kind of public blog for C++ developers - that would be the great thing as well.
Slides for all the sessions would be nice. It's much easier to take notes that way
Amazing talk! The "no raw pointers" inheritance example code is really interesting. Any chance we could have the source code for both the shared and unique version to study? Thanks.
In the final Q&A part, did anyone get the answer about copying big object and than moving it ?
Sean is telling something like :
For big objects, there is an extra move that compiler cannot remove if user defined ?
I didn't get this point, has anyone an explanation ?
Illuminating!
Can we please get the slides /pdf pls the presentation has to be read and read again.
No question if Sean writes a book I'll purchase it asap!
Which book(s) do you recommend to learn the standard Library algorithms and their many uses?
This was by far, one of my most favorite talks of the conference. Seeing a "mess of code" (we've all written code like that) transformed into its final state was a real treat.
It was my first time watching Sean speak - he's a great oral teacher.
Thank you!
@Vandamme:The comment near the end was about passing sink arguments by value. The person commenting noted that passing by value, as opposed passing by rvalue ref and const lvalue ref, may impose an additional move operation. My reply was that yes, passing by rvalue ref can be a win, but it is a combinatoric problem, since you can have multiple sink arguments to a function (common for constructors).
The commenter then noted that you can instead pass by universal reference and use enable_if<> to limit to the desired types to avoid the combinatoric problem. This works, but it is complex.
IMO, passing by value is sufficient in nearly all cases, if move (which should be a constant time operation proportional to the local area of your object, typically small) shows up on a profile in a critical section then by all means, optimize. Here is what the three cases would look like:
// pass by value to ctor and move into place employee(string x, string y) : first_(move(x)), last_(move(y)) { } // pass by all permutations of rvalue and lvalue refs some_class(const string& x, const string& y) : first_(x), last_(y) { } some_class(const string& x, string&& y) : first_(x), last_(move(y)) { } some_class(string&& x, const string& y) : first_(move(x)), last_(y) { } some_class(string&& x, string&& y) : first_(move(x)), last_(move(y)) { } // pass by universal reference and constrain with enable_if template <typename T, typename U> some_class(T&& x, U&& y, enable_if_c< is_same<remove_ref_t<T>, string>::value && is_same<remove_ref_t<U>, string>::value >::type = nullptr) : first_(forward<T>(x)), last_(forward<T>(y)) { }
The last case is probably a bit wrong - but without spending time with the compiler I'd have a difficult time getting it right. Hopefully that makes it clear why I prefer just pass by value.
My favorite talk this time. Perhaps because I work on code base when curly braces are often nested 10 times.
After hearing about raw loops I looked at tutorial examples of boost::gil documentation. Because nothing says "loops" like image and speaker is from Adobe. :)
It looks like one dimensional convolution is std::transform_accumulate (which does not exist in standard library, neither does accumulating output iterator). Or is there such a thing in standard lib?
Two dimensional is a bit trickier you need a view of two dimensional array which provides a one dimensional iterator... And you must do it on every pixel so you need a view iterator.
Here is the challenge I have for myself. Apply a two dimensional convolution to two dimensional array without nested raw loops while maximizing standard library usage. Anyone?
I posted an updated version of the slides from this talk here: https://github.com/sean-parent/sean-parent.github.com/wiki/Papers-and-Presentations
@Sean
Thanks a lot for your explanation above and the slides, everything is clear now for me !
@SeanParent: The code samples illustrating the three ways of dealing with permutation problem are very useful and clearly demonstrate the readability advantages of passing by value. There is just one error there: the snippet with enable_if should std::forward its parameters, not std::move.
@mstone:Thanks - I edited the comment.
Anyone else having trouble using 'gather' function from the slides in vs2012 ?
'not1' refuse to accept the lambda:
[](int v) -> bool { return (v % 2) == 0; }
Have I forgot how to use c++ or is it another visual studio bug?
One of those bad days...
@depths:There is an optional slide I didn't show that discusses the issue. It is on page 209 in this slide deck <https://channel9.msdn.com/Events/GoingNative/2013/Inheritance-Is-The-Base-Class-of-Evil>. That page also shows an implementation using a lambda instead of not1() to do the predicate negation. I'm hoping that C++14 fixes not1().
In case you have trouble viewing the slide - here is the code:
template <typename I, // I models BidirectionalIterator typename S> // S models UnaryPredicate auto gather(I f, I l, I p, S s) -> pair<I, I> { using value_type = typename iterator_traits<I>::value_type; return { stable_partition(f, p, [&](const value_type& x){ return !s(x); }), stable_partition(p, l, s) }; }
@SeanParent:
Question 1:
I'm confused. I've gotten several suggestions, each contradicts the previous one.
For best performance should I pass by value or universal reference?
Is it case by case basis?
Even an extra move could impact performance.
Question 2:
How would you write column based sorting that obeys the previous sort?
It sounds like subrange sorting.
Sorted by first name:
John Smith New York
John Doe Ohio
John Stone Alaska
Micheal Smith New York
Micheal Doe Georgia
Micheal Stone Alaska
Now subrange sorted by state
John Stone Alaska
John Smith New York
John Doe Ohio
Micheal Stone Alaska
Micheal Doe Georgia
Micheal Smith New York
@jerry:
Answer 1: For best performance pass by universal reference or supply all permutations of r-value/l-value. But profile first - it usually will do no better than pass by value and may end up slower since you have more code polluting your icache. Either approach adds size and complexity to your code - you might be better off investing in other optimizations.
Answer 2: Use std::stable_sort() to obey the previous ordering(s). For example, let's say the user clicked on the "state" column - you would sort by state as:
stable_sort(begin(a), end(a), [](const person& x, const person& y){ return x.state_ < y.state_; });
The the user clicked on the "first" column - you would sort by first as:
stable_sort(begin(a), end(a), [](const person& x, const person& y){ return x.first_ < y.first; });
The result would be as in your subrange sorted example - but the idea extends to any number of columns.
Great talk!
In your bad_cow example. Code like:
If (0 == --object_m->count_m) delete object_m;
Also has data race correct? In between the check and the delete, if unlucky somebody on another thread could make a copy to that bad_cow and bump up the ref count thus you will end up deleting the object while someone else thinks it is still valid.
Or does this happen so rarely in practice and code like this is usuallly ok to write?
Ugh I meant race condition in my previous comment.
Actually no, it should be safe. If the ref count did get 0, nothing else can grab a reference to it and bump the refcount.. Apologies!
@Sean: First, thanks for answering questions on here! Very appreciated.
You mention that there's a language defect that requires you to write a move assignment operator. Can you elaborate on what exact defect you were referring to? Why would a "unifying assignment"[1] operator not work (where you take the parameter by value to achieve copy and swap for lvalues and move construction into the temporary for rvalues)? (or am I misunderstanding something here?)
Thanks!
[1]: http://en.cppreference.com/w/cpp/language/as_operator#Copy_and_swap
@Chase:I answered your question in the comment section for my other talk:
https://channel9.msdn.com/Events/GoingNative/2013/Inheritance-Is-The-Base-Class-of-Evil
Search for "operator=" on that page.
@Sean: Sorry I missed that; thanks for the explanation! (I, too, want your book!)
I love to learn new things... and what you explained was amazing, please go on and teach us how to make things as simpler as they can be. Thanks indeed for the talk, I'm eager to read your book. Amaaaaaziiiing!!!!
csr