📄 iter-issue-list.rst
字号:
base iterator, passes the result of this to the function object, and
then returns the result.
to:
The transform iterator adapts an iterator by modifying the
``operator*`` to apply a function object to the result of
dereferencing the iterator and returning the result.
9.12 Transform_iterator shouldn't mandate private member
========================================================
:Submitter: Pete Becker
:Status: New
transform_iterator has a private member named 'm_f' which should be
marked "exposition only."
:Proposed resolution: Mark the member ``m_f`` as exposition
only. Note/DWA: I think this is NAD because the user can't
detect it, though I'm happy to mark it exposition only.
Change::
UnaryFunction m_f;
to::
UnaryFunction m_f; // exposition only
9.13 Unclear description of counting iterator
=============================================
:Submitter: Pete Becker
:Status: New
The description of Counting iterator is unclear. "The counting
iterator adaptor implements dereference by returning a reference to
the base object. The other operations are implemented by the base
m_iterator, as per the inheritance from iterator_adaptor."
:Proposed resolution:
Change:
The counting iterator adaptor implements dereference by
returning a reference to the base object. The other operations
are implemented by the base ``m_iterator``, as per the
inheritance from ``iterator_adaptor``.
to:
``counting_iterator`` adapts an object by adding an
``operator*`` that returns the current value of the object. All
other iterator operations are forwarded to the adapted object.
9.14 Counting_iterator's difference type
========================================
:Submitter: Pete Becker
:Status: New
Counting iterator has the following note:
[Note: implementers are encouraged to provide an implementation
of distance_to and a difference_type that avoids overflows in the
cases when the Incrementable type is a numeric type.]
I'm not sure what this means. The user provides a template argument
named Difference, but there's no difference_type. I assume this is
just a glitch in the wording. But if implementors are encouraged to
ignore this argument if it won't work right, why is it there?
:Proposed resolution: The ``difference_type`` was inherited from
``iterator_adaptor``. However, we've removed the explicit
inheritance, so explicit typedefs have been added. See the
resolution of 9.37x.
9.15 How to detect lvalueness?
==============================
:Submitter: Dave Abrahams
:Status: New
Shortly after N1550 was accepted, we discovered that an iterator's
lvalueness can be determined knowing only its value_type. This
predicate can be calculated even for old-style iterators (on whose
reference type the standard places few requirements). A trait in
the Boost iterator library does it by relying on the compiler's
unwillingness to bind an rvalue to a T& function template
parameter. Similarly, it is possible to detect an iterator's
readability knowing only its value_type. Thus, any interface which
asks the user to explicitly describe an iterator's lvalue-ness or
readability seems to introduce needless complexity.
:Proposed resolution:
1. Remove the ``is_writable`` and ``is_swappable`` traits, and
remove the requirements in the Writable Iterator and Swappable
Iterator concepts that require their models to support these
traits.
2. Change the ``is_readable`` specification. Remove the
requirement for support of the ``is_readable`` trait from the
Readable Iterator concept.
3. Remove the ``iterator_tag`` class and transplant the logic for
choosing an iterator category into ``iterator_facade``.
4. Change the specification of ``traversal_category``.
5. Remove Access parameters from N1530
In N1550:
Remove:
Since the access concepts are not related via refinement, but
instead cover orthogonal issues, we do not use tags for the
access concepts, but instead use the equivalent of a bit field.
We provide an access mechanism for mapping iterator types to
the new traversal tags and access bit field. Our design reuses
``iterator_traits<Iter>::iterator_category`` as the access
mechanism. To that end, the access and traversal information is
bundled into a single type using the following `iterator_tag`
class.
::
enum iterator_access { readable_iterator = 1, writable_iterator = 2,
swappable_iterator = 4, lvalue_iterator = 8 };
template <unsigned int access_bits, class TraversalTag>
struct iterator_tag : /* appropriate old category or categories */ {
static const iterator_access access =
(iterator_access)access_bits &
(readable_iterator | writable_iterator | swappable_iterator);
typedef TraversalTag traversal;
};
The ``access_bits`` argument is declared to be ``unsigned int``
instead of the enum ``iterator_access`` for convenience of
use. For example, the expression ``(readable_iterator |
writable_iterator)`` produces an unsigned int, not an
``iterator_access``. The purpose of the ``lvalue_iterator``
part of the ``iterator_access`` enum is to communicate to
``iterator_tag`` whether the reference type is an lvalue so
that the appropriate old category can be chosen for the base
class. The ``lvalue_iterator`` bit is not recorded in the
``iterator_tag::access`` data member.
The ``iterator_tag`` class template is derived from the
appropriate iterator tag or tags from the old requirements
based on the access bits and traversal tag passed as template
parameters. The algorithm for determining the old tag or tags
picks the least refined old concepts that include all of the
requirements of the access and traversal concepts (that is, the
closest fit), if any such category exists. For example, the
category tag for a Readable Single Pass Iterator will always be
derived from ``input_iterator_tag``, while the category tag for
a Single Pass Iterator that is both Readable and Writable will
be derived from both ``input_iterator_tag`` and
``output_iterator_tag``.
We also provide several helper classes that make it convenient
to obtain the access and traversal characteristics of an
iterator. These helper classes work both for iterators whose
``iterator_category`` is ``iterator_tag`` and also for
iterators using the original iterator categories.
::
template <class Iterator> struct is_readable { typedef ... type; };
template <class Iterator> struct is_writable { typedef ... type; };
template <class Iterator> struct is_swappable { typedef ... type; };
template <class Iterator> struct traversal_category { typedef ... type; };
After:
Like the old iterator requirements, we provide tags for
purposes of dispatching based on the traversal concepts. The
tags are related via inheritance so that a tag is convertible
to another tag if the concept associated with the first tag is
a refinement of the second tag.
Add:
Our design reuses ``iterator_traits<Iter>::iterator_category``
to indicate an iterator's traversal capability. To specify
capabilities not captured by any old-style iterator category,
an iterator designer can use an ``iterator_category`` type that
is convertible to both the the most-derived old iterator
category tag which fits, and the appropriate new iterator
traversal tag.
We do not provide tags for the purposes of dispatching based on
the access concepts, in part because we could not find a way to
automatically infer the right access tags for old-style
iterators. An iterator's writability may be dependent on the
assignability of its ``value_type`` and there's no known way to
detect whether an arbitrary type is assignable. Fortunately,
the need for dispatching based on access capability is not as
great as the need for dispatching based on traversal
capability.
From the Readable Iterator Requirements table, remove:
+-----------------------------------+-----------------------------------+-------------------------+
|``is_readable<X>::type`` |``true_type`` | |
+-----------------------------------+-----------------------------------+-------------------------+
From the Writable Iterator Requirements table, remove:
+-------------------------+--------------+----------------------------+
|``is_writable<X>::type`` |``true_type`` | |
+-------------------------+--------------+----------------------------+
From the Swappable Iterator Requirements table, remove:
+-------------------------+-------------+-----------------------------+
|``is_swappable<X>::type``|``true_type``| |
+-------------------------+-------------+-----------------------------+
From [lib.iterator.synopsis] replace::
template <class Iterator> struct is_readable;
template <class Iterator> struct is_writable;
template <class Iterator> struct is_swappable;
template <class Iterator> struct traversal_category;
enum iterator_access { readable_iterator = 1, writable_iterator = 2,
swappable_iterator = 4, lvalue_iterator = 8 };
template <unsigned int access_bits, class TraversalTag>
struct iterator_tag : /* appropriate old category or categories */ {
static const iterator_access access =
(iterator_access)access_bits &
(readable_iterator | writable_iterator | swappable_iterator);
typedef TraversalTag traversal;
};
with::
template <class Iterator> struct is_readable_iterator;
template <class Iterator> struct iterator_traversal;
In [lib.iterator.traits], remove:
The ``iterator_tag`` class template is an iterator category tag
that encodes the access enum and traversal tag in addition to
being compatible with the original iterator tags. The
``iterator_tag`` class inherits from one of the original
iterator tags according to the following pseudo-code.
::
inherit-category(access, traversal-tag) =
if ((access & readable_iterator) && (access & lvalue_iterator)) {
if (traversal-tag is convertible to random_access_traversal_tag)
return random_access_iterator_tag;
else if (traversal-tag is convertible to bidirectional_traversal_tag)
return bidirectional_iterator_tag;
else if (traversal-tag is convertible to forward_traversal_tag)
return forward_iterator_tag;
else if (traversal-tag is convertible to single_pass_traversal_tag)
if (access-tag is convertible to writable_iterator_tag)
return input_output_iterator_tag;
else
return input_iterator_tag;
else
return null_category_tag;
} else if ((access & readable_iterator) and (access & writable_iterator)
and traversal-tag is convertible to single_pass_iterator_tag)
return input_output_iterator_tag;
else if (access & readable_iterator
and traversal-tag is convertible to single_pass_iterator_tag)
return input_iterator_tag;
else if (access & writable_iterator
and traversal-tag is convertible to incrementable_iterator_tag)
return output_iterator_tag;
else
return null_category_tag;
If the argument for ``TraversalTag`` is not convertible to
``incrementable_iterator_tag`` then the program is ill-formed.
Change:
The ``is_readable``, ``is_writable``, ``is_swappable``, and
``traversal_category`` class templates are traits classes. For
iterators whose ``iterator_traits<Iter>::iterator_category``
type is ``iterator_tag``, these traits obtain the ``access``
enum and ``traversal`` member type from within
``iterator_tag``. For iterators whose
``iterator_traits<Iter>::iterator_category`` type is not
``iterator_tag`` and instead is a tag convertible to one of the
original tags, the appropriate traversal tag and access bits
are deduced. The following pseudo-code describes the
algorithm.
::
is-readable(Iterator) =
cat = iterator_traits<Iterator>::iterator_category;
if (cat == iterator_tag<Access,Traversal>)
return Access & readable_iterator;
else if (cat is convertible to input_iterator_tag)
return true;
else
return false;
is-writable(Iterator) =
cat = iterator_traits<Iterator>::iterator_category;
if (cat == iterator_tag<Access,Traversal>)
return Access & writable_iterator;
else if (cat is convertible to output_iterator_tag)
return true;
else if (
cat is convertible to forward_iterator_tag
and iterator_traits<Iterator>::reference is a
mutable reference)
return true;
else
return false;
is-swappable(Iterator) =
cat = iterator_traits<Iterator>::iterator_category;
if (cat == iterator_tag<Access,Traversal>)
return Access & swappable_iterator;
else if (cat is convertible to forward_iterator_tag) {
if (iterator_traits<Iterator>::reference is a const reference)
return false;
else
return true;
} else
return false;
traversal-category(Iterator) =
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -