←back to thread

178 points todsacerdoti | 10 comments | | HN request time: 0.233s | source | bottom
Show context
codeflo ◴[] No.26340405[source]
I’ve personally never encountered the particular misunderstanding the author dispels here, but I’m sure the post is written from bitter experience. On the one hand, I shouldn’t be that surprised: Unfortunately, programming in C++ is really brutal for people who would rather learn by example than by carefully reading documentation.

But on the other hand, my instinctive reaction is: Come on, is this really something that confuses people? emplace_back is all about constructing something in-place, which is exactly the opposite of moving it there! How can any professional programmer be 180 degrees wrong about the purpose of a function they use regularly?

What I want to say here is that C++ is really hard, and that there are a million subtle things that one simply has to look up instead of making educated guesses. I don’t think people appreciate this difficulty enough.

replies(6): >>26340522 #>>26340785 #>>26344462 #>>26345318 #>>26345544 #>>26346091 #
xKingfisher ◴[] No.26340785[source]
The article did touch on a possible reason for the misunderstanding.

If you already know from previous versions that push_back makes a copy and that C++11 added move semantics and emplace_back, it's not a huge leap to connect the two. Especially if you don't notice push_back's rvalue overload (or understand rvalues).

And if you're new to C++ and are having all of this thrown at you at once it'd definitely be easy to get some crossed wires.

replies(1): >>26341375 #
1. brown9-2 ◴[] No.26341375[source]
As someone new to C++, it seems endlessly confusing that you are supposed to know if a function call is making a copy vs a move by figuring out the signature of the function being called or knowing which one the compiler picks, rather than being explicit about it in the code (with std::move or somehow annotating the call with what you want).
replies(3): >>26341456 #>>26342005 #>>26346289 #
2. xKingfisher ◴[] No.26341456[source]
It's definitely a lot to process.

I found these two articles really helpful when trying to understand moves:

https://abseil.io/tips/55 https://abseil.io/tips/77

Though I'd also say don't worry about it too much, especially at first. If you're copying a lot of temporary objects moving can get you some performance wins, but that's something profiling should be telling you m

replies(1): >>26344848 #
3. junon ◴[] No.26342005[source]
You should always know the signature of a function you're calling. Please be reading docs.

The part I agree with are the method selection semantics. A good rule of thumb (though don't rely on it) is that the "more specific" prototype generally wins.

replies(1): >>26343847 #
4. brown9-2 ◴[] No.26343847[source]
I agree you should know what you are calling when writing code, but there is also a need for people to read the code and understand what the behavior will be. My impression is that C++ relies a lot on implicit knowledge.
replies(1): >>26344364 #
5. vlovich123 ◴[] No.26344364{3}[source]
All languages do.
replies(1): >>26346791 #
6. jeffbee ◴[] No.26344848[source]
Authors should also try to be aware that for some types there's not a meaningful difference between copy construction and move construction.
7. gpderetta ◴[] No.26346289[source]
Well ideally functions shouldn't be moving behind your back, i.e if you write:

  foo(someValue);
someValue will bever be implicitly moved. Either you need an explicit cast (i.e. std move) or someValue is actually an expression returing a temporary or an rvalue.

Of course if foo takes someValue by non const reference it might still modify someValue as it wishes (and moving out of it is just one possible mutation). But this is not a specific issue with moves but with functions taking non const references in general, which should be used only sporadically and hopefully the name makes the mutation clear.

8. Yoric ◴[] No.26346791{4}[source]
Well, many languages try to keep this minimal. C++ doesn't.
replies(1): >>26348894 #
9. ziml77 ◴[] No.26348894{5}[source]
And it's nothing new with move/copy semantics either. Even passing by reference is bad for hiding that. Every time I write C++ I'm tempted to take pointers as parameters in places where you'd normally take a reference just so the call site has an indication of what I'm doing.
replies(1): >>26352898 #
10. junon ◴[] No.26352898{6}[source]
Totally agree.