Boost logo

Boost :

From: Howard Hinnant (hinnant_at_[hidden])
Date: 2002-10-13 08:54:22


On Saturday, October 12, 2002, at 11:19 PM, Terje Slettebø wrote:

>> From: "Howard Hinnant" <hinnant_at_[hidden]>
>
>> </philosophical on/>
>>
>> And hopefully not going to far off track here: The automatic shoulder
>> strap belts that try to help by automatically placing the shoulder
>> strap around you, while leaving you with the job of attaching the lap
>> belt, are a menace to safety and I can't believe that they ever made
>> it
>> into public use.
>
> Do you here refer to the ordinary three-point seatbelts, with a fixed
> lower
> point, a rolling upper point, and the third other side lower point for
> attaching? If that's what you mean, I think that works very well, as
> you
> with one point attachment gives a three-point belt, so the attachment
> attaches both the diagonal and horizontal belt. Why would that be a
> menace
> to safety, and what would you recommend instead?

I /knew/ I was getting too philosophical! :-)

I'm referring to the motorized rolling upper point. The motorized
action has led more than one inattentive person to believe that the car
had fastened their safety belt for them. So they did not even notice
that their lap belt was left unfastened.

>> Fwiw, I've used --c.end() and am not sorry for it! :-)
>
> If you do that on Intel C++ and STLPort for e.g. c=std::string, you
> get a
> compile-time error, as c.end() is not a modifiable lvalue. :) In other
> words, whether or not that work depends on the platform, and is
> therefore
> not portable.

I believe that this is a good argument for wrapping pointers up in an
iterator adaptor. I do not believe it is a good argument for making
temporaries const. --c.end() is not inherently unsafe. It simply does
not work if the iterator turns out to be a pointer. This is a quirk of
the language and nothing more.

Indeed, using a pointer as an iterator is significantly less safe than
putting an iterator adaptor around the pointer. You can do all kinds
of unsafe things with the pointer that the wrapper prohibits, and my
experience has shown that a significant number of people indeed do
these unsafe things:

std::string::iterator i = 0;
...
if (i == 0)
    ...

char* p1, p2;
... // p1 and p2 could be set to point at anything
str.erase(p1, p2);

Oh, and here's a favorite that a customer recently brought to my
attention:

str.insert(0, 1, 'a');

Error : ambiguous access to overloaded function
'std::string::insert(char *, unsigned long, char)'
'std::string::insert(unsigned long, unsigned long, char)'

(this last example is not unsafe, just irritating - same as --c.end())

So just because --c.end() compile-times if the iterator turns out to be
a pointer, does not mean one should try to emulate this detail of
pointer-iterators. If a class becomes too inconvenient to use, I'm
either going to not use it, or subvert it. Personally I find --c.end()
(and potentially ++c.begin()) both safe and convenient.

There is only one case I can think of where pointer-iterators are
superior to (typical) class iterators:

const_iterator ci = ...;
iterator i = const_cast<iterator>(ci);

I think this functionality (if not the precise syntax) would be a good
thing to emulate.

-Howard


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