27 ms·
Some people might ask why I chose to make the parameter of BlackBox::store an rvalue reference rather than an lvalue reference and force the client code to use
by merogin 11y ago
Some people might ask why I chose to make the parameter of BlackBox::store an rvalue reference rather than an lvalue reference and force the client code to use std::move. While it is true that an lvalue reference would also have worked, if I did that, it would be impossible to write code like crate.store(std::make_unique<Gadget>(beeper, flasher));. I also happen to think that forcing the client to use std::move at the call sites is good rather than bad, because it communicates the intended effect to the reader.
Passing unique_ptr by value is the correct option here, it will accept temporaries just fine.
And in my opionion, if you want safety quarantees like that, use Rust. I was a fan of the new C++ standards a while ago, but after having used them for some time, I found C is a lot nicer language. There's just way too much mental overhead when trying to write "idiomatic C++" and the compiler errors you sometimes get are just a waste of developer time.
- nice_byte 11y agoSomeone brought up this point during another discussion and initially I agreed with them. However, someone else suggested that if the function has more parameters, an exception might happen when passing the arguments for the other parameters, so the transfer of ownership won't happen, but the caller will have already lost the ownership. Passing by rvalue reference means the caller retains ownership until the very last possible moment.
- merogin 11y agoDo you mean something like this? http://ideone.com/8tPPHy http://ideone.com/8tPPHy
- nice_byte 11y agoYes. It seems to work, but it might be a coincidence. The order of argument evaluation is undefined. It might be that the exception gets thrown before the ownership is transferred, but it's just luck. I have modified your example a bit, to better trace what's happening: http://ideone.com/tgh0xe http://ideone.com/tgh0xe
- merogin 11y agoAnd it won't work when switching the parameter order of byval, so you're correct. That's quite nasty.
- frankzinger 11y agoTip: insert manual newlines into verbatim/code blocks to make them more readable: Some people might ask why I chose to make the parameter of BlackBox::store an rvalue reference rather than an lvalue reference and force the client code to use std::move. While it is true that an lvalue reference would also have worked, if I did that, it would be impossible to write code like crate.store(std::make_unique<Gadget>(beeper, flasher));. I also happen to think that forcing the client to use std::move at the call sites is good rather than bad, because it communicates the intended effect to the reader.
- userbinator 11y agoThere's just way too much mental overhead Exactly. Instead of understanding the very simple concept of which object owns, I now have to understand that concept, how std::unique_ptr works, and rvalue references? How does it work with conditional ownage? I also mostly use C instead of C++, but I admit that automatic constructor/destructor calls and virtual functions (as long as the class hierarchy doesn't become too deep) are quite useful. Lambda expressions too. I think that as long as you can use C++ while still having an idea what the language is doing implicitly what you would've had to do explicitly in C, you can get the advantages without the disadvantages.
- golergka 11y ago> Exactly. Instead of understanding the very simple concept of which object owns, I now have to understand that concept, how std::unique_ptr works, and rvalue references? While one concept is simpler, the other is controlled by compiler, while object ownership is only controlled by the developer himself.