Loading user information from Channel 9

Something went wrong getting user information from Channel 9

Latest Achievement:

Loading user information from MSDN

Something went wrong getting user information from MSDN

Visual Studio Achievements

Latest Achievement:

Loading Visual Studio Achievements

Something went wrong getting the Visual Studio Achievements

C++ Seasoning

1 hour, 17 minutes, 12 seconds


Right click “Save as…”


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.


Follow the discussion

  • Oops, something didn't work.

    Getting subscription
    Subscribe to this conversation
  • Great talk! And, indeed, we _need_ Sean to write a book! Smiley

  • Christian SemmlerChristian Semmler

    +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.

  • cjlovecjlove

    Great talk! Looking forward to watching it again once it is online.

  • ztxcztxc

    When will the video be put online?

  • jzsjzs

    yes Great 3 suggestions and the vivid examples, +1 for the book, just can not wait :D

  • Eric [MSFT]EricBattalio Visual C++ PM

    +1 for the book.

    The examples were well thought out and consumable by less-experienced C++ developers like me.

  • dzyashudzyashu

    +100 for the book

  • dzyashudzyashu

    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.

  • felix9felix9 the cat that walked by itself

    can we have the slide uploaded here ? Smiley

  • dzyashudzyashu

    @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 Big Smile

  • 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.

  • VandammeVandamme

    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?


  • John DubchakJohn Dubchak

    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.


  • MichaelMichael

    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.

  • depthsdepths

    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 <http://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) };

  • jerryjerry

    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?

  • jerryjerry

    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.

  • RyanRyan

    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?

  • RyanRyan

    Ugh I meant race condition in my previous comment.

  • RyanRyan

    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!

  • ChaseChase

    @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?)


    [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:


    Search for "operator=" on that page.

  • ChaseChase

    @Sean: Sorry I missed that; thanks for the explanation! (I, too, want your book!)

  • csrcsr

    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!!!!


Remove this comment

Remove this thread


Comments closed

Comments have been closed since this content was published more than 30 days ago, but if you'd like to continue the conversation, please create a new thread in our Forums, or Contact Us and let us know.