CppCon 2014: Michael Caisse 'The Canonical Class'

preview_player
Показать описание
--
--
It was a simpler time. A period in which every college student and learn-C++-in-a-weekend duffer could write a class with the assuredness that it would behave as desired when assigned and copied. There was a check list. Complete the checklist, add some domain specific behaviour, bake in the regression oven, and you were done.

Enter C++11 with its fancy new use of the delete keyword, additional applications of explicit, rvalue references, and some perfect forwarding. How are you to write a "simple" class? Should you include a swap? What does movable mean and are there expected semantics? When is the noexcept specifier used?

During this session we will explore the boilerplate of a C++11 class. The session will touch on rvalue references, move semantics, perfect forwarding, explicit, noexcept, initializer lists, and more as it applies to producing the desired semantics for our classes and structs.
--
Michael Caisse has been crafting code in C++ for nearly 25-years. He is the owner of Ciere Consulting which provides software consulting and contracting services, C++ training, and Project Recovery for failing multidisciplinary engineering projects.
--

*-----*
*-----*
Рекомендации по теме
Комментарии
Автор

nice talk, thanks. it shows how complex the rules for C++ is getting at each iteration. i am not sure where the language is headed but surely something needs to be done.

victornoagbodji
Автор

The object you have a reference to is going to get destroyed almost immediately after the move takes place. That is generally the definition of a move. So there is no uncertainly about when resources will be cleaned up. You are supposed to clean them up in the destructor (RAII) which by definition gets called almost immediately after the move.

newsmanfedora
Автор

Steve Robb, I agree with you: at 14:30 its not garbage but int is initialized to zero there. Thats how I remember reading it as well. I was also wondering why he said that...

tryingtocorrect
Автор

The version of the move implementation at 40:18 won't work for lvalue, because of reference collapsing rules. Need to use std::remove_reference additionally.

mykhailohnap
Автор

22:50 I can only assume that's just a silly typo that slipped in when creating the slides: The new buffer he creates if his current one isn't big enough is still the size of the old one ('size'), and not that of the new one ('rhs.size'). So for anything that's larger this is gonna go wrong.

TheCreat
Автор

I don't think implementing move in terms of swap is a good idea because it adds uncertainty to when resources are cleaned up. When I assign to an object (move or copy), I'd like to know for sure that the resources before the assignment will be cleaned up right then and there.

fmatthew
Автор

14:35 he said i is garbage, but i is constructed via brace initializer, so how is it garbage?

versatran
Автор

@22:25 In Copy Constructor head should be head=buffer + (rhs.buffer - rhs.head);

raghureddy
Автор

14:30 - "i is garbage" - how? The copy of the standard I'm reading says that, during list initialisation (which you have because you're using curly brackets) that an empty list means that the object is value initialised, which for int is zero initalisation. The compilers I have access to seem to concur.

SoftNFuzzy
Автор

Bug in the code at 23:07. The statement buffer = new uint8_t(size); should be buffer = new uint8_t(rhs.size);

nileshkkulkarni
Автор

I guess on slide at 30:10 the string ctor parameters are in wrong order and vector<>::insert takes different types of arguments

antonbikineev
Автор

He doesn't explain it very well, I think but he's trying to point out that

template &lt; typename V &gt; struct A { V v; }; is different from

template &lt; typename V &gt; struct B { B() : v() { } V v; };

when V is primitive.

artyerkes