Subject: Re: [boost] Interest in StaticVector - fixed capacity vector
From: Dave Abrahams (dave_at_[hidden])
Date: 2011-10-19 13:26:44
on Wed Oct 19 2011, Nevin Liber <nevin-AT-eviloverlord.com> wrote:
> On 16 October 2011 06:50, Dave Abrahams <dave_at_[hidden]> wrote:
>>> It's still silent, as it isn't the same interface even though the
>>> actual call looks the same.
>> Well, now we could pick nits over the meaning of "same interface."
> Are the "Requires" clauses in the Standard part of the interface or
Yes, absolutely. But that's just one function. I think I had in mind
the total interface of the class, frankly I've forgotten at this point.
I see a container that can never store more than N items, for some
reasonably small N, as fundamentally, semantically different from one
that is highly likely to be able to store any M items you have to deal
with, and for which you can't determine a hard limit N ahead of time
(no, max_size() doesn't countâthat's typically just
numeric_limits<size_t>::max()). I grant you that we don't have a very
strict way of expressing this difference in a specification, but I think
that's just missing. I wouldn't, except in very special circumstances,
consider one of those containers to be a suitable replacement for the
other, despite the similarity of the specification text. Would you?
> I see the answer to that question as something fundamental, not
> picking nits.
> In my point of view they are part of the interface, as they describe
> when it is legal for me to make a particular function call.
Yes, but I think there's something else in the interface (abstractly)
that you may not be accounting for, and that clearly makes these two
push_backs different, even if you choose the throwing semantics.
>>> In some sense it is O(1), since N is bounded, but I know what you
>>> mean. :-)
>> There's also the nonthrowing part.
> I agree. Then again, the only alternative is not providing swap at all.
Sure. I'm not arguing there's something wrong with the throwing swap in
this case; I'm just saying the optimization of "no dynamic allocation,
ever" has consequences that ripple through the interface.
>> I'm not. Â If you think I am, you've misconstrued me. Â I'm just trying
>> to understand the design space and represent a point-of-view about
>> handling likely programmer errors that I think is important and
> When you mess with programmer's expectations, you get programmer
A programmer who doesn't adjust his expectations when replacing
something essentially unbounded with something essentially bounded is in
for a rude surprise no matter what is done about this particular
Sounds like you just don't want to appreciate the point-of-view I'm
representing. That's OK, but I don't think I'll follow up on this post
in that case.
>> I do very much dislike the idea of having multiple interfaces for what
>> is essentially the same semantics.
> Of course, I'm arguing they are different interfaces, but to address
> this point, we have multiple interfaces for the same semantics all the
> time. c.push_back(x) is just c.insert(c.end(), x), c.clear() is just
> c.erase(c.begin(), c.end()), etc.
I believe you are misunderstanding. In fact, c.insert(c.end(),x) does
not (or did not, in C++03) give the same exception-safety guarantees as
> Just today I had to show someone the swap trick for releasing space in
> a vector because there is no obvious way to do it in C++03; I don't
> consider that a good thing.
Sorry, I don't see the relevance.
>> There are certainly applications where it's knowable statically that
>> the limit can never be violated where one might want to drop in a
>> bounded vector in place of std::vector, and having to spell push_back
>> some other way, as though it were essentially different, is ugly.
> I don't think we can resolve this. I see them as different
> interfaces; you may not. Subtle interface differences lead to subtle
-- Dave Abrahams BoostPro Computing http://www.boostpro.com
Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk