From: Neil Butterworth on 1 Nov 2009 22:28 Khan wrote: > @Neil: T does not require a default ctor. My app is constructing the > T, not any standard library function (unless I'm missing something). You have to construct the T object somehow before you pass it to the pop() function. Admittedly, this does not absolutely require a default constructor, but it seems strange to me to write code like this: T t("foo"); // or whatever parameters are required s.pop( t ); when the only thing you do with the t instance is to immediately overwrite it in the pop() function. Neil Butterworth -- [ See http://www.gotw.ca/resources/clcm.htm for info about ] [ comp.lang.c++.moderated. First time posters: Do this! ]
From: Nick Hounsome on 1 Nov 2009 22:28 On 2 Nov, 02:58, Khan <chen...(a)my-deja.com> wrote: > For everybody that suggested the exception-safe answer, that applies > to T pop(), not to bool pop(T&). I just read Sutter where he addresses > this issue, and in fact the relevant Item mentions that bool pop(T&) > doesnt have the exception-safety issues. He says that the Real Problem > with this design is that pop has two responsibilities: pop and return. > I say, so what? > > @Neil: T does not require a default ctor. My app is constructing the > T, not any standard library function (unless I'm missing something). I think that you will find that the books rejecting bool pop(T&) do so because they are considering it as a replacement for the standard methods rather than as an addition. bool pop(T&) DOES have exception issues but only if it is the only sort of pop method available. For example suppose that you want to compare and pop the top elements of two collections. In general it is best to separate functions into throwing bits that don't alter the state and non-throwing bits that do alter the state. These can then always be combined into higher level methods with the same semantics. Indeed this is the idea behind the exception safe "copy-and-swap" idiom for assignment. This is why I agreed that there should be a variant (but not a replacement) but with a different name. I suppose that an argument against it as an extra is that by omitting this variant naive developers are less likely to go wrong. -- [ See http://www.gotw.ca/resources/clcm.htm for info about ] [ comp.lang.c++.moderated. First time posters: Do this! ]
From: Jeff Schwab on 1 Nov 2009 22:56 Khan wrote: > Why is there no variant of pop() in the standard library that returns > the top element? I can understand why there is a void pop() - for > efficiency. But why isnt there also a variant that returns the top > element - bool pop(T&), so that those who want to use it can? It'd be > so much simpler to write a routine while (x.pop(t)) { } rather than > while (x.empty()) { t = x.top(); x.pop(); } and I suppose the > atomicity would help MT etc operations too. Such a function can already be implemented as a non-member function, implemented in terms of the existing member functions. pop(T&) would not form part of what Stepanov calls the "computational basis" of the type. There is additionally a reason that some people, including me, find a signature like pop(T&) disturbing: It requires the prior existence of a non-const T. In particular, the T in question may not have been initialized to any meaningful value. Initializing the T from the back of the container, then popping the value, is a more semantically graceful alternative, even if it requires an extra line of code. You could also have pop assign the result to a dereferenced iterator; a pointer to the T in question would work, or you could write an Input_iterator, e.g. "back_remove_iterator," that compared equal to "end" when the underlying container was empty. By the way, some C++ libraries, e.g. the OpenAccess EDA database, have lots of function signatures like the one you've suggested, but in reverse: The result is returned by value, and a "status" bool is accepted by reference. > The one reason I can think of (Dont give a way to the user to do > inefficient things) has counterarguments: I think you're looking at this backwards. When you release a standard, justification ought to be necessary for providing features, not for omitting them. -- [ See http://www.gotw.ca/resources/clcm.htm for info about ] [ comp.lang.c++.moderated. First time posters: Do this! ]
From: Keith H Duggar on 2 Nov 2009 13:49 On Oct 30, 5:33 pm, Khan <chen...(a)my-deja.com> wrote: > Why is there no variant of pop() in the standard library that returns > the top element? I can understand why there is a void pop() - for > efficiency. But why isnt there also a variant that returns the top > element - bool pop(T&), so that those who want to use it can? It'd be > so much simpler to write a routine while (x.pop(t)) { } rather than > while (x.empty()) { t = x.top(); x.pop(); } and I suppose the > atomicity would help MT etc operations too. > > The one reason I can think of (Dont give a way to the user to do > inefficient things) has counterarguments: > - A lot of people are going to write T t = x.pop() anyway. Cant > prevent that. > - Prevent user from shooting themselves in the foot is not C++ > philosophy. > - It may not be inefficient in many cases, so why not leave it to the > user? > > I'm sure this must have been asked before, but I guess my searchfu is > inadequate, sorry. Thanks in advance, > chengiz Several have already posted good (and standard) answers. Here is another different take. class member interfaces should be 1) complete 2) minimal. In the case of a stack clearly we need the capability to access the top without modification so T & .top() is a must. Second we need the capability to pop as efficiently as possible hence void .pop() . At that point the class interface is complete (as far as access and popping go) so adding a top+pop (shift) member variant would violate the "minimal interface" design criterion. As a demonstration that it is complete see how simple it is to provide a free function in your own custom library to get the extra shift behavior you want template < class T > bool shift ( std::stack<T> & s , T & t ) { if ( !s.empty() ) { t = s.top() ; s.pop() ; return true ; } return false ; } So just code that up in your gadget.hpp and be happy ;-) KHD -- [ See http://www.gotw.ca/resources/clcm.htm for info about ] [ comp.lang.c++.moderated. First time posters: Do this! ]
From: Martin B. on 2 Nov 2009 19:42 Keith H Duggar wrote: > On Oct 30, 5:33 pm, Khan <chen...(a)my-deja.com> wrote: >> Why is there no variant of pop() in the standard library that returns >> the top element? (....) >> >> The one reason I can think of (Dont give a way to the user to do >> inefficient things) has counterarguments: >> - A lot of people are going to write T t = x.pop() anyway. Cant >> prevent that. >> (....) > > Several have already posted good (and standard) answers. Here > is another different take. > > class member interfaces should be 1) complete 2) minimal. In the > case of a stack clearly we need the capability to access the top > without modification so T & .top() is a must. Second we need the > capability to pop as efficiently as possible hence void .pop() . > > At that point the class interface is complete (as far as access > and popping go) so adding a top+pop (shift) member variant would > violate the "minimal interface" design criterion. > While there are arguments for class *member* interfaces being minimal, I'd say that's no reason for the class interface to be minimal. That is, if "we" think shift is a useful interface, then it should be provided along with the class (as a free function) and "we" shouldn't require the user to roll her own. > As a demonstration that it is complete see how simple it is to > provide a free function in your own custom library to get the > extra shift behavior you want > > template < class T > > bool shift ( > std::stack<T> & s , T & t ) > { > if ( !s.empty() ) { > t = s.top() ; > s.pop() ; > return true ; > } > return false ; > } > Having to provide all[*] these "simple" helper functions does not strike me as a sign of completeness. [*] With "all" I am referring to the issue that one often heard response to questions such as the OP is that it's "easy" or "simple" or "trivial" to add said functionality via a free function. The question then is why it ain't part of the library already (together with documentation about possible issues regarding exceptions etc.). br, Martin -- [ See http://www.gotw.ca/resources/clcm.htm for info about ] [ comp.lang.c++.moderated. First time posters: Do this! ]
First
|
Prev
|
Next
|
Last
Pages: 1 2 3 4 Prev: Simplester MetaLoop Next: Announcement: Enhanced search engine for C/C++, with Firefox/IE |