[C++-sig] Re: C arrays mk 2

David Abrahams dave at boost-consulting.com
Thu Oct 16 22:51:10 CEST 2003


Raoul Gough wrote:

>>Go look up the Sequence requirements in the standard.  A Sequence is
>>defined by two iterators... uh, whoops: I should have said
>>"Container". "Sequence" adds mutability.
>>
>>"works with iterators" is irrelevant to what it *is* in essence, since
>>it says nothing about how it's used once it's initialized.
> 
> I think you're stretching a point here. 

OK, you're right.  Perhaps iterator_range_container_facade.

> The iterator_pair template
> does little more than store two iterators and define some types. In
> fact, the three member functions other than begin() and end() are only
> provided for convenience, since they simply use std::advance or
> std::distance. 

I try not to decide naming based on implementation details.  Is it 
really "just for convenience", or is it so that it satisfies the 
interface requirements of the container suite?

> So from that point of view, it really is just a pair of
> iterators. Importantly, it doesn't manage storage, in contrast to the
> all of the standard containers that also accept a pair of iterators
> for construction.

Can you find storage management as part of the Container concept in the 
standard?  OK, I see below that you can.

>>>I've actually wondered about the name
>>>myself, but not for the reason you mentioned: it doesn't work with
>>>every pair of iterator instances, because they have to specify a valid
>>>range, like the requirements for std::distance ("last must be
>>>reachable from first"). i.e. it's not the same as std::pair<iterator,
>>>iterator>, because there are further requirements on the values used.
>>
>>Right, and because it's not, fundamentally, a pair of iterators.  It's
>>a facade for the Container concept.
> 
> 
> OK, yes, it provides *part* of the container interface, since it has
> the typedefs and begin() and end() and some syntactic niceities like
> operator[]. However, there is an important distinction in terms of
> storage management as I already mentioned. From the way you described
> it, calling something std::list would be wrong, because that's an
> implementation detail.

No, it's not.  Its list-ness affects externally visible properties like 
complexity of insert, iterator invalidation, etc.  If you can build 
something with the same properties using a different data structure, by 
all means go ahead and call it "list".

> Anyway, paragraph one of the container requirements says:
> 
>   "Containers are objects that store other objects. They control
>   allocation and deallocation of these objects through constructors,
>   destructors, insert and erase operations."
> 
> There is also no way that ~iterator_pair is going to "apply the
> destructor to every element", as is required of containers.

OK, point taken.

>>>Also, I'm also not sure that it could really be called immutable,
>>>since you can replace elements (just not insert or delete them).
>>>Anyway, can you suggest an alternative name?
>>
>>container ;->

Well, I'm stumped for a name at the moment.  I think we need a new 
concept in the hierarchy, less-refined than Container.

>>>>As a side note, please use boost::detail::iterator_traits instead of
>>>>std::iterator_traits, for portability reasons.
>>>
>>>OK - will fix these.
>>>
>>>
>>>>As another side note, endline layout
>>>>
>>>>  template<typename Iterator>
>>>>  iterator_pair<Iterator>::iterator_pair (iterator_param begin
>>>>                                          , iterator_param end)
>>>>
>>>>is banned in Boost.Python.  Should be, e.g.:
>>>>
>>>>  template<typename Iterator>
>>>>  iterator_pair<Iterator>::iterator_pair (
>>>>      iterator_param begin, iterator_param end)
>>>>
>>>>;->
>>>
>>>?What do you do when the parameter list itself gets too long for a
>>>single line? I usually use the vertical layout as soon as I have to
>>>split the line the first time.
>>
>>   template<typename Iterator>
>>   iterator_pair<Iterator>::iterator_pair (
>>       iterator_param begin
>>     , iterator_param end)
>>
>>Just avoid endline layout; all other line breaks are fine.
>>
>>
>>>>I'll stop picking nits with your excellent work now.
>>>
>>>Well, a uniform coding style is always a good thing. I'm just
>>>wondering how much effort this will involve, especially considering
>>>that Emacs auto-indent won't co-operate with what you use (or have you
>>>customized this somehow?).
>>
>>Yes.  I have enclosed my .emacs; you'll need the latest cc-mode (like
>>from CVS).
> 
> 
> Far out. Does this also handle indentation to "<" as a template
> argument list delimiter?

Mostly.  I have found a few cases which need tweaking.  Every once in a 
while when I allow myself I improve it a little bit.
>>>BTW, why do you dislike the vertical style?
>>
>>I have no problem with vertical style, but you can google for endline
>>layout to read about the associated evils.
> 
> 
> Well, I did have a look with Google but didn't find anything
> particularly conclusive. I understood that "endline layout" means
	> aligning a column of equally-indented code near the right-hand margin,
> which creates problems when the textual components change length
> (e.g. renaming an identifier). Is that about right? 

Yes.

Endline layout is what happens when you have an unmatched open delimiter 
in the middle of the line:

     foo(bar

What happens is that you're then compelled to line things up under bar. 
  Not only does that make poor use of space, it means a whole lotta 
busywork indentation adjustment when someone changes the name of foo to 
"fu" or "foobarre".

This isn't one of those things that kills a project, but you need to 
choose some style and I prefer to choose one that has a nice rationale 
so I can stop thinking about whether I chose right ;->

 > I initially
> thought you wanted to avoid columnar layouts entirely.

No, you can see lots of examples of that in my code I'm sure.

-Dave






More information about the Cplusplus-sig mailing list