From: Neil Butterworth on
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
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
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
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
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! ]