CppCon 2017: Nicolai Josuttis “The Nightmare of Move Semantics for Trivial Classes”

CppCon.org
-
Presentation Slides, PDFs, Source Code and other presenter materials are available at: github.com/CppCon/CppCon2017
-
Assume, we implement a very simple class having just multiple string members. Even ordinary application programmer prefer to make it simple and fast.
You think you know how to do it? Well beware! It can become a lot harder than you initially might assume.
So, let’s look at a trivial class with multiple string members and use live coding to see the effect using different implementation approaches (using constructors passing by value, by reference, by perfect forwarding, or doing more sophisticated tricks).
Sooner than later we will fall into the deep darkness of universal/forwarding references, enable_if, type traits, and concepts.
-
Nicolai Josuttis: IT Communication
Nicolai Josuttis (www.josuttis.com) is an independent system architect, technical manager, author, and consultant. He designs mid-sized and large software systems for the telecommunications, traffic, finance, and manufacturing industries.
He is well known in the programming community because he not only speaks and writes with authority (being the (co-)author of the world-wide best sellers The C++ Standard Library (www.cppstdlib.com), C++ Templates, and SOA in Practice), but is also an innovative presenter, having talked at various conferences and events.
-
Videos Filmed & Edited by Bash Films: www.BashFilms.com
*-----*
Register Now For CppCon 2022: cppcon.org/registration/
*-----*

Пікірлер: 141

  • @ChronosSk
    @ChronosSk3 жыл бұрын

    Well, I would argue for the pass-by-value-then-move option: It expresses the idea fairly simply, while giving the compiler everything it needs to optimize away the overhead. "Everything should be made as simple as possible, but not simpler."

  • @sprytnychomik
    @sprytnychomik3 жыл бұрын

    Question: How many mallocs does X require. C++ programmer: Four! No, two! No, six! Wait... it depends. C programmer: How many do you want?

  • @jplflyer
    @jplflyer3 жыл бұрын

    This was truly frightening.

  • @bobbymah2682
    @bobbymah26826 жыл бұрын

    I can always count on Nicolai to present relatively new C++ constructs in a clear, concise, and idiomatic fashion

  • @canberksonmez3146
    @canberksonmez31465 жыл бұрын

    That's a very good presentation after all. It summarizes many things regarding pass-by-value and pass-by-reference techniques, and clearly describes the mentioned problems. I like it.

  • @MirrorsEdgeGamer01

    @MirrorsEdgeGamer01

    3 жыл бұрын

    Yes, at uni they told us to pass by reference; I now see how wrong they were.

  • @phusicus_404

    @phusicus_404

    3 ай бұрын

    ​@@MirrorsEdgeGamer01Only if you don't need a copy in memory or the value mustn't change. Yeah.

  • @Victarus
    @Victarus6 жыл бұрын

    Some good information, but I fell like the "Haha, isn't C++ awful?" stuff is uncalled for when the example code is contrived in such a way to emphasize edge/expert cases. The solution at 13:25 (pass by value and use std::move) is simple, straightforward, and provides the optimal performance the talk is supposedly aiming at; everything else is just a tangent about argument forwarding (passing the `const char*` into `std::string` without creating a temporary), and non-explicit constructors with default arguments (the issues with `Cust c = ...;`). Since it's never presented as such though, it makes it look like this really straightforward thing (using move semantics to improve performance) is a huge mess because these other interface issues are being thrown on top of that. Worse still though, even those things thrown into the mix, the straightforward solution at 13:25 _still works perfectly_ for the example given: It creates a special case for the one-argument const char* constructor (which is self-inflicted by the issues above), but it works, is easy to read/write, and is super straightforward. Going into templates is just overkill for its own sake without even an acknowledgement that no, this is completely unnecessary, and requiring this sort of thing in a real-world environment _probably_ indicates something wrong with your design.

  • @spacechild2

    @spacechild2

    4 жыл бұрын

    In the summary at 52:06 he says that he would actually recommend pass by value + std::move because it's good enough and easy to reason about.

  • @27182818284590452354
    @271828182845904523546 жыл бұрын

    "And the rest of you? Do you hate C++?" Well, after watching the horrible mess just before that, kinda.

  • @homomorphic

    @homomorphic

    3 жыл бұрын

    It's not a terrible mess. It covers details that you simply can't control in other languages at all. Sometimes another languages implementation might do the right thing for a particular case and sometimes it might not, but in C++ you can always control it (if somewhat awkwardly). As Nicolai explains here, if you use value semantics with move, then you will match or exceed the performance of other languages 99% of the time and if you go to template instantiation control you can beat those other languages for the 1% of the time where it matters. So if you make your life complicated unnecessarily with C++ that's on you, because you don't have to.

  • @slyfox3333

    @slyfox3333

    Ай бұрын

    @@homomorphic Not even true. In rust its trivial to do this.

  • @grostig
    @grostig6 жыл бұрын

    Very humorous, enjoyed it.

  • @LordNezghul
    @LordNezghul6 жыл бұрын

    You cannot move your template constructors to other compilation unit, so you let everything visible by compiler so it can use optimizations. If compiler can see everything and use optimizations then just use pass-by-value. But if you want to move your constructors to other compilation unit and maybe even use pimpl idiom for ABI compatibility then for best performance you have to write multiple constructors.

  • @tohopes
    @tohopes6 жыл бұрын

    Consider skipping to 17:00 if the earlier stuff seems too repetitive.

  • @mand7993
    @mand79936 жыл бұрын

    Correct me if I'm wrong - it doesn't matter how you receive it, by const reference or by const pointer, the initialization first(f) and last(l) will create copy. So eventually we have 4 mallocs, not 2 char* c = new char[5]{}; c[0] = '1'; c[1] = '2'; c[2] = '3'; c[3] = '4'; std::string a(c); // copying delete c; std::cout

  • @nileshkkulkarni
    @nileshkkulkarni5 жыл бұрын

    Mind blowing ..... wow..... mindddaaaaaa blooooowwwwwinnnnngggggggg...... This is exactly what I was looking out for. I am so much thankful to you Nicolai. WOW!

  • @SuperBorisl
    @SuperBorisl3 жыл бұрын

    Great talk, thank you Nico!! May I ask is there any video of second part of move semantics by Nico on that conference? Anyone?? To be honest Nico was one of my favorite authors since ever.

  • @vesk4000

    @vesk4000

    8 ай бұрын

    Yeah, I'd love to see that too

  • @mcbernnard4303
    @mcbernnard43036 жыл бұрын

    I hope C++20 will have a cool feature that a programmer can say hey compiler give me a lollipop.

  • @deleteddeleted1940

    @deleteddeleted1940

    Жыл бұрын

    prolly will be in c++42

  • @jankodedic3130
    @jankodedic31306 жыл бұрын

    Why should initializing Cust (Base) with VIP (Derived) be valid? If VIP had any additional data members, wouldn't they be sliced? Shouldn't it just be: Derived is a Base, but Base isn't Derived??

  • @MSheepdog

    @MSheepdog

    6 жыл бұрын

    If you had a function taking is a Cust and only needing to look at it's members, then initialising one from VIP is fine. The only problem case would be if you tried to cast your Cust into a VIP since it wouldn't have those members.

  • @deltarambo6230
    @deltarambo62304 жыл бұрын

    There is a mistake in the slides at 46:10 that is the number of moves in the second version, which should be 7 moves instead of 5 moves. If you don't believe me, then go back to the slides at 15:45 and count the number of moves yourself.

  • @benoitrousseau4137
    @benoitrousseau41376 жыл бұрын

    This talk was very interesting.

  • @NXTangl
    @NXTangl5 жыл бұрын

    When he said that the arrayness of the arguments didn't decay I went "Oh _god_." Because that means every length of string literal bloats the binary for no good reason. If there is any nontrivial action in your perfect forwarding constructor...

  • @Cromius771
    @Cromius7714 жыл бұрын

    What if he added Cust(Cust& cust) = default; ?

  • @ColorfirePluma
    @ColorfirePluma5 жыл бұрын

    On my machine, using MSVS 19.1030324, adding the line "using customer::customer" makes "VIP v{"Boss"};" fail to compile, citing ambiguous constructor.

  • @7xr1e20ln8

    @7xr1e20ln8

    4 жыл бұрын

    Of course. Boss is never a VIP. It's done the right thing.

  • @dirtbikersteve
    @dirtbikersteve6 жыл бұрын

    24:00 you have to use std::decay i think?

  • @ryannicholl8661
    @ryannicholl86615 жыл бұрын

    Microsoft is correct here. It should be const char *& not const char *, because you make a non-universal reference i.e. a rvalue reference to a const char *&& (non-forwarding)

  • @teranyan
    @teranyan2 жыл бұрын

    The reality is that C style string pointers simply don't belong in a modern software base written in C++. Just use std::string or make your own string class and always enforce that. You are basically fighting a needless battle of trying to account for all permutations of c++ strings and c strings when you don't need to do that in the first place.

  • @janisir4529

    @janisir4529

    Жыл бұрын

    const char * = fast

  • @ultradude5410

    @ultradude5410

    Жыл бұрын

    Yeah, but literals though Can’t get away

  • @zoltankurti

    @zoltankurti

    Жыл бұрын

    Gotta love including dozens of kloc code to get an expanding char array.

  • @michal.gawron
    @michal.gawron6 жыл бұрын

    23:15 By compiler's vote, gcc and clang are right. ;-)

  • @michal.gawron

    @michal.gawron

    6 жыл бұрын

    DemonLordChaos By what? ;-)

  • @hansiraber

    @hansiraber

    6 жыл бұрын

    en.wikipedia.org/wiki/Myth_of_the_flat_Earth

  • @tamikanomara1687
    @tamikanomara16876 жыл бұрын

    There must be words about code bloat, instructions cache and inlining... Did I miss it?

  • @LemonChieff
    @LemonChieff4 жыл бұрын

    I'd use pass by value and move (which should really be implicit and guaranteed where it is possible and efficient [ie: for common cases such as in constructors]) and avoid defaulted arguments. In fact google strictly forbids it. I think efficient code should be idiomatic and simple. If it's not then it's a bug in the language. And I'm not coding around a language, it's too painful.

  • @DFsdf3443d
    @DFsdf3443d5 жыл бұрын

    14:46 but aren't the "Joe" and "Fix" literals copied in to the constructor arguments f and l before they are moved? So 2 mallocs when they are created and then 2 when they are copied and then 2 moves ?

  • @oktal3700

    @oktal3700

    5 жыл бұрын

    The constructor std::string::string(const char *) will obtain the length of the literal, call malloc() to allocate a buffer at least as big as that, and copy the characters into that buffer. So it mallocs once per string argument.

  • @rabingajmer3293
    @rabingajmer3293 Жыл бұрын

    Moving an aggregate class containing rvalue/lvalue references members as function parameters??

  • @rajaravivarmar
    @rajaravivarmar5 жыл бұрын

    This is depressing. All I could say is, make it a standard to guarantee that the compiler will construct it in place if it an object is constructed out of a temporary.

  • @TheD4T4
    @TheD4T46 жыл бұрын

    strlen overheat for constant literals with known size wasn't covered. Also, as pointed out somewhere in comments, you get only weak exception guaranties, but can achieve strong without runtime overheat

  • @martinkutny8026
    @martinkutny80266 жыл бұрын

    The person from the audience at 48:43 pointed out the only intelligent solution in this whole presentation - make members public and use aggregate initialization. That will do the right thing and generate optimal code in all cases while saving you from the forwarding constructor insanity. I honestly don't understand the sarcastic reaction from the presenter.

  • @joshodom9046

    @joshodom9046

    6 жыл бұрын

    Because you lose encapsulation. Theoretically it should be fine, as long as nobody abuses the fact that your private members are public, but it's no longer enforceable by the compiler. Encapsulation might not matter in this particular class, but the chosen technique should work for complicated classes as well.

  • @martinkutny8026

    @martinkutny8026

    6 жыл бұрын

    It's a wrong example. Encapsulation brings no advantage here. But people might (and many will) get the wrong impression that this is universally the right thing to do and will emulate this in their code. If encapsulation is really what you need, you could use property-based or builder approach. You'll get the same result with respect to number of creates / copies / moves, but much better API design and readability. Language trickery such as this, are one of the prime reasons C++ gets the bad reputation of a super-complex language (which it really is). But your code does not have to be like that. Nothing wrong with this as an exercise and a conference is a good place to discuss things like this. But the presenter should not give off the impression, that this is the normal and recommended thing to do in day-to-day production code.

  • @joshodom9046

    @joshodom9046

    6 жыл бұрын

    For this specific class, I agree that encapsulation buys you nothing. Correct me if I'm wrong, but if you write a builder or setters, I believe you have to make the same decision as he showed with the constructor. I personally got the impression that he was just exploring nuances of the language, not recommending that you write all constructors with template madness, but I guess he could have mentioned it at least once. At the end of the talk, he did recommend the approach of pass-by-value with move construction. One thing I think he should have mentioned is that he's really talking about worst-case compiler guarantees, not about the actual performance of code compiled under optimized settings. I believe all shown constructors would be compiled to identical machine instructions, which further supports pass-by-value with move construction. I'm not a c++ expert, and I'm writing a chess engine in it (where performance is proportional to engine strength), so knowing techniques that will help the compiler create optimized machine code is what's really useful for me, moreso than worst case guarantees. Regardless, this talk did help me understand the language a bit better.

  • @martinkutny8026

    @martinkutny8026

    6 жыл бұрын

    With property-based builder you would have to write a copy setter and a move setter (or just one templated forwarding setter) for each member. That is some boilerplate code. But dealing with one member at a time, you will at least be spared from the combinatorial explosion of passing multiple / optional arguments and need no SFINAE hacks. You are right about the optimizations. Compilers nowadays can eliminate a lot of unnecessary copying. But such optimizations before C++17 were only at the discretion of compiler implementers. Whether a particular instance of a copy/move will be optimized out depends on the C++ standard level, the level of implementation of said standard in the compiler, compiler flags. I mean, good luck telling just by looking at the source code, whether a particular copy will be optimized out or not. If this presentation proved anything, it is that in C++ you can do object-oriented OR zero-overhead OR readable code. But you can pick only 2 out of 3. You need to choose what is more important in your context. I usualy prefer zero-overhead AND readable. But sometimes OO is required (e.g. by corporate coding style) and then I opt for OO AND readable at the cost of possibly some overhead.

  • @HtS643KyS6555GxQ3edA
    @HtS643KyS6555GxQ3edA3 жыл бұрын

    I love that C++ std library book.

  • @xavierthomas1980
    @xavierthomas19806 жыл бұрын

    9:00 Missing the ending double-quote for sting literal "nico"

  • @a_ij6269
    @a_ij62695 жыл бұрын

    a) why do you have to support any possible string representation in the first place? b) why not use method overloading for the 1 argument case? instead of sfinae + default args c) if you have to support all cases why not use a builder pattern. i don't see the point. the stuff i have to do in java is much worse

  • @gumo77

    @gumo77

    3 жыл бұрын

    b) Exactly. Default arguments are a C legacy, and they don't belong to OO code. If you want to call the constructor with 3 different signatures, you just specify 3 different constructors. And your problems suddenly go away.

  • @hervealexanian2684
    @hervealexanian26845 жыл бұрын

    I am such a nerd I had more fun watching this than most comedy routines

  • @Ethanmoe
    @Ethanmoe Жыл бұрын

    Why not use string_view?

  • @manofacertainrage856
    @manofacertainrage8565 жыл бұрын

    The punchline for C++17 is at 41:03

  • @justinlink1616
    @justinlink161611 ай бұрын

    A good number of the problems observed here are also avoided if default parameters are not used. (And of course I now see that that is mentioned at the end.)

  • @homomorphic
    @homomorphic3 жыл бұрын

    Any good engineer will trade off clarity and simplicity against performance. There may be times when performance supercedes clarity and simplicity, but in practice, that's not very often. the language must allow for the latter case, but the programmer is responsible to make the trade-off appropriately for the use case. I enjoyed this talk.

  • @gzozulin

    @gzozulin

    2 жыл бұрын

    C Programming Language = clarity and simplicity AND performance

  • @harshtiwari9588
    @harshtiwari95885 жыл бұрын

    I like this person! He is a good narrator.

  • @MatkatMusic
    @MatkatMusic6 жыл бұрын

    before watching this, I watched Herb Sutter's talk "Back To Basics: Essentials of Modern C++ Style" from CppCon 2014, where he explains how to choose the right solution for a constructor that involves std::string. kzread.info/dash/bejne/qqKltq19aNiqZpc.html is herb's talk.

  • @raidenluikang5532
    @raidenluikang5532 Жыл бұрын

    Just use struct Cust{ std::string first, second; int id; }; without constructor, and initialize it as { "Joe", "Fix", 42 } :)

  • @DarkLevis
    @DarkLevis6 жыл бұрын

    How come creating a string cause a malloc?

  • @arthur.passos

    @arthur.passos

    5 жыл бұрын

    oh boy...

  • @StanleyPinchak

    @StanleyPinchak

    4 жыл бұрын

    A string might be the concatenation of other strings, or may take input from the user, a file or network I/O. How can you know the length at compile time of all possible contents for a string. Since you can not, the string class must be able to dynamically allocate storage from the heap or other memory pool.

  • @kamall94
    @kamall945 жыл бұрын

    Please how much it cost your book about templates

  • @SuperToughnut
    @SuperToughnut6 жыл бұрын

    I was thinking about writing some c++ code again but this video depressed me. This kind of talk should never be necessary. C++ doesn't have to be challenging. However, in the process of trying to make it better, the governor's of c++ have made it more confusing. I want to write code to get work done. But because c++ has to carry the baggage of legacy c++ for backwards compatibility we all suffer. No one is going to rewrite legacy code and new code in the same project should probably follow the pattern of the legacy code (if it's written well).

  • @videogamer24385

    @videogamer24385

    6 жыл бұрын

    Except this kind of talk is kind of geared towards library writers and more "This is what's going on under the hood of the standard library". If you *really* need enable_if_t and other type trait helpers in regular application code to do relatively simple things, you probably are doing something wrong.

  • @SonicFan535

    @SonicFan535

    6 жыл бұрын

    The #1 takeaway of this talk for most people should be to just pass by value (and move into the members) in your constructors 99% of the time. It's easy to write and despite not being 100% "perfect" (a couple of unnecessary moves) it's still way better than the default solution you would get in any other language. You don't have to delve into the confusing parts of C++'s move semantics and enable_if as long as you're not trying to author some kind of extremely low-overhead library.

  • @X_Baron

    @X_Baron

    6 жыл бұрын

    His "customer" class example in the slides is misleading. Later on it becomes clear that he is talking about the Standard Library.

  • @bonbonpony

    @bonbonpony

    6 жыл бұрын

    Library writers? Really? So a simple Customer class is now a library thing and not client code?

  • @SonicFan535

    @SonicFan535

    6 жыл бұрын

    Bon Bon If the customer class doesn't need to construct with absolutely 0 overhead in every single use case, the simple thing to do in client code would be to just write the constructor in the one way that is almost always good enough: Cust( std::string first, std::string last = "", int id = 0 ): first( std::move( first ) ), last( std::move( last ) ), id( id ) {}

  • @samolisov
    @samolisov2 жыл бұрын

    36:30 I cannot get why does VIP v2{v1} work when we used !std::is_same_v for SFINAE. VIP is not the same as Cust and we should face with the same problem with the copy constructor as before, shouldn't we?

  • @IllumTheMessage
    @IllumTheMessage6 жыл бұрын

    Good stuff.

  • @boltactionpiano7365
    @boltactionpiano73654 жыл бұрын

    Constructor(string& value)

  • @NXTangl
    @NXTangl5 жыл бұрын

    Why were the first four minutes of a C++ talk a long argument for Rust?

  • @askeladden450

    @askeladden450

    2 жыл бұрын

    I'm not experienced in rust at all, but how does rust solve this issue?

  • @NXTangl

    @NXTangl

    Жыл бұрын

    ​@@askeladden450 a bit late but: in Rust the issue simply would not arise. Everything moves, so you would simply take the strings by value, and if you don't want to transfer ownership you would simply call `s.clone()` (which actually implicitly calls `Clone::clone(&s)` via Rust's trait-based overloading.)

  • @leshommesdupilly
    @leshommesdupilly Жыл бұрын

    Omg ! I get it ! I just don’t have to care about having too much mallocs !

  • @leshommesdupilly

    @leshommesdupilly

    Жыл бұрын

    Just have to upgrade my cpu to don’t care anymore !

  • @Antagon666

    @Antagon666

    Жыл бұрын

    Imagine doing this with very large array eg 4k image with 32MB of data. Just for creating a object you have to allocate and deallocate 128MB of memory. Now imagine having multiple images.

  • @masheroz
    @masheroz2 жыл бұрын

    The second version is the best. It is the simplest that doesn't require extravagant code. Any move from this to the templated code would need to be backed up by performance testing.

  • @super_cyb0rg226
    @super_cyb0rg2265 жыл бұрын

    I had this on as white noise while at work. Wasn't really paying attention. Then I looked over when the video hit 12:30, and I nearly threw up at my desk. That is disgusting...

  • @finn2001
    @finn20012 жыл бұрын

    I used c++ 1998-1999, looks like am better staying Java.

  • @KilgoreTroutAsf
    @KilgoreTroutAsf5 жыл бұрын

    Great job! I hate C++ now.

  • @carlschumann
    @carlschumann2 жыл бұрын

    And the winner is Java? 🧐

  • @shaksb8617

    @shaksb8617

    Жыл бұрын

    or c# :)

  • @lenkite
    @lenkite5 жыл бұрын

    Umm.. either use C++ 17 string_view or std::move in the construction initialisation. Not even sure why the last horrible template solution got discussed. I think Nicolai missed having coffee.

  • @seditt5146

    @seditt5146

    4 жыл бұрын

    You don't know why he generated and example to show you problems that exist in the language?

  • @OLEGUBAN
    @OLEGUBAN6 жыл бұрын

    Why not just use "Cust(std::string f, std::string l, int i) : first(f), last(l), id(i) {}" and let the compiler figure out that it's ok to move rather than copy both arguments in this particular case? The simple task of passing a couple strings to a constructor must be simple. The "std::move()" solution looks like a winner when contrasted to the horrible "enable_if" / "requires" solution, but both solutions are equally horrible when compared to "first(f), last(l)".

  • @Aidiakapi

    @Aidiakapi

    6 жыл бұрын

    Oleg Gubanov He covers that in the video. It's on the slide "passing by value".

  • @MSheepdog

    @MSheepdog

    6 жыл бұрын

    " and let the compiler figure out that it's ok to move rather than copy both arguments in this particular case" The problem is the compiler might not figure that out, especially if you're running in a debug build which you don't want to be slow just because you were too lazy to write the moves yourself.

  • @OLEGUBAN

    @OLEGUBAN

    6 жыл бұрын

    It's not that I'm lazy. Consider students and majority of developers. They have to be taught the accidental complexity of `std::move` (including the fact that it does not actually move anything) and r-value references - all just to pass a couple of strings to a constructor without unnecessary performance loss. Compiler seems to be the only place where that accidental complexity can be dealt with, letting the developer focus on the essential complexity of the task at hand.

  • @agudo2007

    @agudo2007

    6 жыл бұрын

    Mr. Oleg Gubanov: the compiler can not transform the copy constructions in the source code to moves. The copy constructions have a potential side effect of allocations. Getting maximum performance is tricky, what I see some comments here miss is that C++ is just about the only language that lets you try for maximum performance. If you don’t like the complications of maximum performance, then use C++ in a more straight forward way

  • @Aidiakapi

    @Aidiakapi

    6 жыл бұрын

    agudo2007 To be completely fair here, the standard *does* permit the compiler to omit the copies or turn them into moves in certain cases. (Notably for return values.) This is one of the few (if not only) optimization which is allowed to change the behavior of the program. One compiler might opt for a copy, whereas another might move or do nothing at all.

  • @YourCRTube
    @YourCRTube6 жыл бұрын

    A practical solution is to use ref-counted strings, either immutable or copy-on-write and pass by const reference. Strings are too small and too widely used to micro mange their creation and destruction manually, but too expensive to copy to be used by value and not to care.

  • @bapluda
    @bapluda2 жыл бұрын

    "requires"? So C++ syntax is becoming C#. I think I am going back to plain C thank you. Yep plain C struct with all the fields public is more productive in a team because everybody understands it.

  • @phusicus_404

    @phusicus_404

    3 ай бұрын

    Concepts are brilliant, you just don't want to learn new

  • @halbesbyte
    @halbesbyte6 жыл бұрын

    Why not just use Cust(std::string f, std::string l, int i) : first(std::move(f)), last(std::move(l)), id(i) {} ? Arguments are passed by value, which means they are moved if rvalues references are passed: else copied.

  • @OLEGUBAN

    @OLEGUBAN

    6 жыл бұрын

    This is exactly what the author recommends to use when he summarizes his talk

  • @XiremaXesirin

    @XiremaXesirin

    6 жыл бұрын

    He proposed exactly that solution about a third of the way into the lecture. He also brought up some potential issues with that approach. Maybe watch the whole video before you leave comments?

  • @halbesbyte

    @halbesbyte

    6 жыл бұрын

    Well I didn't bother to watch the video to the end (I was about 1/3 in and still no mentioning of pass by value). A 60 min video about a point that can be told in less than 5 Minutes. It's disgusting to pull in meta-template programming or these duplicate overloaded constructors in this simple case. The simple solution is so straight forward, there is no point in introducing all these complicated and flawed variants.

  • @JoahW

    @JoahW

    6 жыл бұрын

    It does result in potentially more moves than the crazy template version, though the optimizer will likely remove them (and the difference will probably be negligible in vast majority of use cases even with optimizations disabled.) A lot of these lectures are far more engaging at 1.5x or even 2x speed, by the way.

  • @MSheepdog

    @MSheepdog

    6 жыл бұрын

    That solution still isn't perfect, the crazy template stuff cut down on a couple of moves, and plain old struct initialisation with no constructors would also be faster, but would then run into issues with derived classes and such. I think the whole point of the talk was that with c++ it's really hard to get perfect performance with simple enough use cases.

  • @Spiderboydk
    @Spiderboydk2 жыл бұрын

    This is a good example of why I switched from C++ to C. Less effort on language BS means more effort on real problem solving. :-)

  • @godDIEmanLIVE

    @godDIEmanLIVE

    2 жыл бұрын

    Problem with that argument is, you can just write what you would write in C in C++. From a purely technical stand point, C as a language is completely obsolete.

  • @Stierguy1
    @Stierguy14 жыл бұрын

    This should be basic for c++ programmers. The lesson is "don't make poor choices about what value category and how qualified my function's arguments are". There are way more wrong ways to do something than right ways. Other programming languages say "malloc, shmalloc". It's not hard to be better than that.

  • @nooan79
    @nooan79 Жыл бұрын

    What a mess. The use of an std::string is an implementation detail of Cust and it should not be exposed in the constructor(s). Instead, the constructor should accept as argument a generic string type (e.g. string_view) and then store internally (to a std::string/a buffer/something else). Yes that implies a copy (but not necessarily a heap allocation). If copies affect performance negatively, which should only happen with exceptionally long strings or with many, many constructions of Cust in loops, then rethink the architecture.

  • @ginobean737
    @ginobean7374 жыл бұрын

    I don't know if I'm misunderstanding something, but when you pass in a 'const char *' to initialize a std::string, the std::string does NOT take ownership of that 'const char *'. It copies it. Also, the literal const char * is NOT created on the heap. So, if you see "Joe", it's NOT being created on the heap. Given that these two INACCURACIES occurred within the first 15 minutes of the video, I stopped watching this video..

  • @CppCon

    @CppCon

    4 жыл бұрын

    Gino Lee, you are misunderstanding. The two statements that you make are correct, but Nico never says otherwise.

  • @Antagon666
    @Antagon666 Жыл бұрын

    Still better than rust.

  • @sarfok.frimpong8545
    @sarfok.frimpong85455 жыл бұрын

    Please if you comment that c++ is ridiculous ,hard or what ever then you've not come to think of type of programmer you are and what you are really doing in programming field. And remember this tutorial is not for beginners.

  • @aydinhoe6355
    @aydinhoe63556 жыл бұрын

    :))))))) really the nightmare nightmare of c++ . . .

  • @sixjac
    @sixjac5 жыл бұрын

    Don't make C++ 20 full stop and get rid of C++17, you are fucking up the language, it is MEANT to be complicated! You are changing too much shit.

  • @Runoratsu
    @Runoratsu6 жыл бұрын

    Hmm. The talk is interesting, but as soon as he tries to talk more loudly, Mr. Josuttis' voice becomes so shrill and grating it's hard to concentrate on what he actually says. =/

  • @countbrapcula-espana
    @countbrapcula-espana Жыл бұрын

    Rust

  • @Phantom-lr6cs

    @Phantom-lr6cs

    Ай бұрын

    &'static str &'static _ tons of moronic amprsands and tons of single quotes lol thank you rust-Fanboy rust is as ugly as it can be XD

  • @4otko999
    @4otko9994 жыл бұрын

    perfect is the worst enemy of good. the correct answer is to ignore all this bs, pass by reference and enable optimizations

  • @user-nw8pp1cy8q

    @user-nw8pp1cy8q

    3 жыл бұрын

    And you are wrong because compiler can't optimize copies in most cases. Actually best option is to pass by value and move-initialize fields because this more easy to optimize.