Boost logo

Boost :

From: Howard Hinnant (hinnant_at_[hidden])
Date: 2002-10-13 13:31:03


On Sunday, October 13, 2002, at 12:59 PM, Terje Slettebø wrote:

> I'd like to get your comment on --c.end(), after reading the above, if
> you
> still think it's safe in the general case. Especially regarding the
> guarantees given in the standard.

I believe that --c.end() is safe and portable for those iterators that
are both bidirectional and known to have non-pointer implementations.
In the standard this includes list, deque, map, multimap, set and
multiset. For string and vector, --c.end() is not portable. It is
safe in the sense that it won't silently do the wrong thing. But it
may fail to compile due to implementation details. You may call that
unsafe. I may label it irritating. <shrug>

> Why not instead use begin()+c.size()-1? It's safe and portable.

It is safe and portable provided c supplies random access iterators.
Another way to write it is:

c.end() - 1

> Why take such unnecessary risks, when there are safe alternatives?

If I were working with std::vector or std::string, and needed to be
sure that my code was portable, I would use c.end()-1. There may be
times I would have to preferred to spell that as --c.end(). I
personally find it more elegant. If someone is writing a container
that sports random access iterators, and I will be a client, I would
prefer to have either option available to me (as std::deque provides).

Getting back to the Filesystem Library:

> As a result of pre-review comments, the Filesystem Library just
> reviewed had const stuck on a bunch of member functions which return
> by value but take no arguments. For example:
>
> const iterator begin() const;
>
> What is your take on that?

I don't think this is a make or break decision. But I could easily
imagine myself getting a little irritated when I tried to do something
like ++begin(), only to find out that begin() returned a const
iterator. Irritated enough to not use the class? Probably not.
Irritated enough to request a change in the interface so that I could
do ++begin() ? Probably (I think I may have just done that).

This "safety" is degrading the user experience for me. And I don't
feel that I've been protected from anything that I might have easily
and accidently done. I feel like just another guy standing in line for
coffee and knowing I'll have to settle for tepid coffee, because some
numb-nuts scalded himself once and successfully sued.

Yeah, its a safer world now ... <yawn>

If the reason for making begin() return a const iterator is because you
might want to change that to const iterator& someday, that sounds like
a good insurance policy for internal code, especially code that is
still under design. But for a widely distributed library, I'm not
buying it. You need to nail down your interface before you ship.
Either return by (const) reference or return by value. Make your best
decision and go with it.

Just my .02.

-Howard


Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk