Boost logo

Boost :

From: David Abrahams (abrahams_at_[hidden])
Date: 2001-02-28 20:21:18


----- Original Message -----
From: <yahoo_at_[hidden]>
To: <boost_at_[hidden]>
Sent: Wednesday, February 28, 2001 3:15 AM
Subject: [boost] Re: Iterator Adaptor not using traits as template args

> --- In boost_at_y..., "David Abrahams" <abrahams_at_m...> wrote:
> >
> >
> > In nearly all the examples we could think of, the amount of typing
> needed to
> > actually use iterator_adaptor was considerably reduced. Can you give
> an
> > example that shows how things have become worse?
> >
> > We're also seriously considering moving the Pointer parameter to the
> end of
> > all type parameter lists (since it is only needed for compilers
> without
> > partial specialization), and of removing the Pointer and Reference
> > parameters from the _pair_generators (since these can always be
> deduced for
> > a const/non-const pair of iterators).
> >
>
> Well, I did not really considered the amount of typing, because I'm
> afraid that I'm not a good enough programmer to be slowed by my typing
> speed :-(
> At first, it was just that using iterator traits to describe iterator
> properties just "felt right" to me (that's what I use in my own code).
> Sure it makes another class template, but I think that there is no
> additionnal complexity as it is a known (I would say Standard) idiom.
> I mean that we don't have std::value_type< typename Iterator>
> std::pointer<typename Iterator> et al. thoses properties are grouped
> together in std::iterator_traits<> so that is the standard way of
> expressing iterator properties.

The standard idiom for expressing a collection of iterator properties is to
list them, c.f. std::iterator<class Category, class T, class Distance =
ptrdiff_t,
class Pointer = T*, class Reference = T&>

Normally, std::iterator_traits<T> is used for inquiry about an iterator, not
as a way to specify traits for a new iterator.

When creating a new iterator type, there is often no existing, appropriate,
deducible T for which std::iterator_traits<T> supplies all the correct
traits.

That leaves us passing std::iterator<class Category, class T, class Distance
= ptrdiff_t,
class Pointer = T*, class Reference = T&>, (or boost::iterator<> for broken
implementations) as we had been doing in our earlier examples.

the problems with using std::iterator<> are:
1. The defaults cause more type parameters to be specified than neccessary.
For example, every constant forward, bidirectional, or random-access
iterator needs ALL 5 of the parameters every time. That's just an example,
though... also note that the category must be specified even when it can be
deduced from a base iterator type.

2. You've just added the extra characters std::iterator<...> to your use of
iterator_adaptor:

boost::iterator_adaptor<base_type, policies, std::iterator<typename
std::iterator_traits<base_type>::iterator_category, value> >

   =vs=

boost::iterator_adaptor<base_type, policies, value>

>We can expect Boost library users to
> know it, and the principle of least surprize will lead they (us, me
> included) to believe that iterator properties are expressed with a
> traits class (default being provided by the Standard) rather than
> an ORDERED (:-() set of 5 classes.

I agree that an ordered set of 5 parameters can be problematic from a
usability standpoint, whether they are template or function arguments. We're
investigating Alexy's idea of allowing users to name the parameters; a kind
of keyword-template-arguments feature.

> As the exemple is set by the standard, we can expect that people
> needing custom properties will express them using traits so
[sic]

> having to pass typename traits::value_type, typename
> traits::reference, typename traits::pointer
> etc... will not buy them anything.

The example set by the adaptor generators in the library show substantial
simplification due to the new interface. Do you have counterexamples?

> The others either do not need
> customization (no problem) or could just use a
> iterator_traits_helper<...> with your default parameters.
>
> The ease of use is also ease of reuse (of existing code), and I think
> that it would have been easier for me to adapt code from current
> interface to the old one(grouping templates arguments in one
> iter_traits_helper<>) than the other way (splitting traits, I cannot
> easly decide which argument to keep so I must use all of them :-( )

That's why there is a release cycle at boost. The iterator adaptor lib
wasn't released yet. ;-)

> Furthermore, I think it could be a useful addition to have
> some template meta-code to manipulate / check iterator properties
> (for exemple common_properties< Traits1, Traits2>::traits,
> are_compatible<Traits1, Traits2>::ret, is_sensible<Traits>::ret)
> and this is most certainly cleaner with encapsulation of thoses
> properties in traits.

Why not just use: is_sensible<std::iterator_traits<iterator_adaptor<...> >
>::ret
??

-Dave


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