5 ms·
> I recommend sticking with push_back for day-to-day use. This Google tip of the week gives a good explanation (explicit vs implicit) for why to prefer push ba
by wrsh07 2y ago
> I recommend sticking with push_back for day-to-day use.
This Google tip of the week gives a good explanation (explicit vs implicit) for why to prefer push back vs emplace if you don't need the benefit of emplace: https://abseil.io/tips/112 https://abseil.io/tips/112
In particular:
> Let me answer that question by asking another: what do these two lines of code do?
vec1.push_back(1<<20);
vec2.emplace_back(1<<20);
> The first line is quite straightforward: it adds the number 1048576 to the end of the vector. The second, however, is not so clear. Without knowing the type of the vector, we don’t know what constructor it’s invoking, so we can’t really say what that line is doing
- CamperBob2 2y agopush_back always sounds clunky and dissonant to me. Gotta wonder what was wrong with ".append" -- guess it wasn't applicable to stack-based containers or something.
- wrsh07 2y agoI wonder if they designed the APIs for vector, list, deque, etc together On deque it all feels fairly natural. Ruby's shift and unshift are cool, but I always struggle to remember the words
- kragen 2y agoyes, they did ruby and js got shift and unshift from perl, which got shift from sh, where it's the only way to iterate over an array or other list. (also, sh only has one array) in the old country, instead of shift and unshift, we said cdr and cons. we didn't have push and pop; if we wanted to mess with the backside of a list we had to reverse it first. but our code ran ten times as fast as ruby and had implicit undo at some point don hopkins suggested, i think it was, eat and barf for, respectively, push and pop on the front end. the back end would then necessarily be boof and shit (not shift). betcha wouldn't forget which end those pertained to
- beached_whale 2y agoAppend to which side? Push and pop are terms of are for queues and stacks which containers can be and the back and front tell us which end of the container we mean
- CamperBob2 2y agoAppend implies the back or end of something, while "prepend" would be the analogous term for the front.
- throwaway2037 2y agoFrom a natural language perspective, I agree. In practice, however, I see far more container libraries use the terms: (1) add or append and (2) insert w/ index (instead of prepend). Do you know of any container libraries that use the term prepend? From time to time, I use it in a function for some kind of business logic, e.g., "prependMeetingInvite()".
- mewpmewp2 2y agoJS dom manipulation has prepend and append. These always felt quite natural to me. While push back feels weird. The act of pushing feels out of place and I also think back and front may also be ambiguous.
- timthorn 2y agoPrefix would be the traditional term.
- jkaplowitz 2y agoWouldn’t prefix be the traditional counterpart to suffix, not to append?
- timthorn 2y agoYes, it would. But prefix is also a verb that means to "to add something before another thing" which is the counterpart to append.
- the_mitsuhiko 2y agoYou can look at the earliest sources of the STL from 1994 pre-standardization and the names were already used back then. It's not entirely unsurprising considering even back then there was a vector and a deque.
- layer8 2y agoYou have Alexander Stepanov to thank: http://stepanovpapers.com/STL/DOC.PDF http://stepanovpapers.com/STL/DOC.PDF The thought was to have the symmetry of push and pop, on both ends of a sequence container. See table 11 on page 22 (actually page 24 of the PDF).
- mort96 2y agoI agree that push_back/pop_back is a bit clunky, but I've gotten used to it tbh. What I haven't gotten used to is the terms "shift" and "unshift" from other languages. But I never get confused by C++'s push_front/pop_front. And I think the consistency has some value. Is it enough value to warrant the extra verbosity? Meh, I think it's more or less a wash.
- tzs 2y agoA minor problem with "append" (and "prepend" for the front) is that, as far as I know, there isn't a really satisfying word for the reverse operation. A search for the opposite of "append" suggests "remove", "subtract", "detach", "disconnect", "disjoin", "unfasten", "reduce", "diminish", and more. None of them really have the same "at the back" connotation that "append" has. "Push" and "pop" are well known from stacks so it makes sense to use them for operations on one end of list-like containers. That still leaves the problem of what to call the similar operations on the other end. I suppose we could sidestep that problem by only providing them at one end. So say push() adds to the back and pop() removes from the back. If you want to operate at the front just reverse the list, do your push or pop, and then reverse the list again and let the optimizer deal with eliminating the two reverses. :-)
- dataflow 2y agoappend is used for sequences. push_back is used for individual elements. Maybe not the most intuitive terminology, but there's value to separating the two ideas.
- throwaway2037 2y agoWe cannot see the full code context from the blog post, but I felt similar about push_back() vs emplace_back() in the blog post example. Either of these are more explicit and clear to me: widgets.push_back(Widget(foo, bar, baz)); widgets.emplace_back(Widget(foo, bar, baz)); ... even if computationally worse.
- edflsafoiewq 2y agoThat argument is wrong, since push_back(1<<20) can invoke an implicit conversion to value_type, so by the same dint you also cannot say what that line is doing.
- loeg 2y agoIf you don't allow implicit constructors in your codebase, this can be avoided.
- dataflow 2y agoIf you make the mistake of creating an implicit constructor when you shouldn't, yeah, but that's your mistake. The argument is fine.
- g15jv2dp 2y agoAre you saying that for the first line, one could say that... > Without knowing the type of the vector, we don’t know what constructor it’s invoking, so we can’t really say what that line is doing.
- dataflow 2y agoNo, that's not what I'm saying. I have no idea where you saw me saying anything about those 2 lines or vectors in my sentences. I am saying 1-arg constructors that aren't semantically "conversions" from that arg need to be be explicit, not implicit. If you make them implicit, that's your mistake; tools can catch that mistake statically.
- g15jv2dp 2y agoUh. I'll try to be more explicit. Let's say that someone in a library somewhere has made what you consider to be a mistake. Or they consider something to be a conversion but the constructor is not trivial. For the push_back construction, can you then say what the call does without knowing the types?
- vintagedave 2y ago> suppose you have a std::vector<std::vector<int>> and you want to append a number to the end of the first vector, but you accidentally forget the subscript. ... if you write my_vec.emplace_back(2<<20), the code will compile, and you won’t notice any problems until run-time. How is this not caught by the type system? 2<<20 is clearly no way, whatsoever, compatible with a vector<int> type.
- dullcrisp 2y agoIiuc, it’ll call the vector<int> constructor with 2<<20 and make you a huge vector.
- deleted 2y ago[deleted]
- wrsh07 2y agoThe compiler can't read your intention. Emplace means "forward these arguments to the constructor", so it forwards those arguments to the constructor (in this case, vector<int>). With push back it would be caught by the compiler because you can't implicitly convert 2<<20 to a vector<int>