⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 iter-issue-list.rst

📁 boost库提供标准的C++ API 配合dev c++使用,功能更加强大
💻 RST
📖 第 1 页 / 共 5 页
字号:
+++++++++++++++++++++++++++++++++++++
 Iterator concept and adapter issues 
+++++++++++++++++++++++++++++++++++++

:date: $Date: 2004/01/27 04:50:51 $

.. contents:: Index

===================================
 Issues from Matt's TR issues list
===================================


9.1 iterator_access overspecified?
==================================

:Submitter: Pete Becker 
:Status: New 

The proposal includes::

  enum iterator_access { 
     readable_iterator = 1, writable_iterator = 2,
     swappable_iterator = 4, lvalue_iterator = 8
  }; 

In general, the standard specifies thing like this as a bitmask
type with a list of defined names, and specifies neither the exact
type nor the specific values. Is there a reason for iterator_access
to be more specific?

:Proposed resolution: The ``iterator_access`` enum will be removed,
   so this is no longer an issue.  See the resolution to 9.15.


9.2 operators of iterator_facade overspecified 
==============================================

:Submitter: Pete Becker 
:Status: New 

In general, we've provided operational semantics for things like
operator++. That is, we've said that ++iter must work, without
requiring either a member function or a non-member function.
iterator_facade specifies most operators as member
functions. There's no inherent reason for these to be members, so
we should remove this requirement. Similarly, some operations are
specified as non-member functions but could be implemented as
members. Again, the standard doesn't make either of these choices,
and TR1 shouldn't, either. So: ``operator*()``, ``operator++()``,
``operator++(int)``, ``operator--()``, ``operator--(int)``,
``operator+=``, ``operator-=``, ``operator-(difference_type)``,
``operator-(iterator_facade instance)``, and ``operator+`` should
be specified with operational semantics and not explicitly required
to be members or non-members.

:Proposed resolution: Not a defect. 

:Rationale: The standard uses valid expressions such as ``++iter``
  in requirements tables, such as for input iterator.  However, for
  classes, such as ``reverse_iterator``, the standard uses function
  prototypes, as we have done here for
  ``iterator_facade``. Further, the prototype specification does
  not prevent the implementor from using members or non-members,
  since nothing the user can do in a conforming program can detect
  how the function is implemented.


9.3 enable_if_interoperable needs standardese
=============================================

:Submitter: Pete Becker 
:Status: New 

The only discussion of what this means is in a note, so is
non-normative. Further, the note seems to be incorrect. It says
that enable_if_interoperable only works for types that "are
interoperable, by which we mean they are convertible to each
other." This requirement is too strong: it should be that one of
the types is convertible to the other.  N1541 48

:Proposed resolution: Add normative text. Relax requirements in the
  proposed way.

  Change:

    [*Note:* The ``enable_if_interoperable`` template used above is
    for exposition purposes. The member operators should be only be
    in an overload set provided the derived types ``Dr1`` and
    ``Dr2`` are interoperable, by which we mean they are
    convertible to each other.  The ``enable_if_interoperable``
    approach uses SFINAE to take the operators out of the overload
    set when the types are not interoperable.]

  To:

    The ``enable_if_interoperable`` template used above is for
    exposition purposes.  The member operators should only be in an
    overload set provided the derived types ``Dr1`` and ``Dr2`` are
    interoperable, meaning that at least one of the types is
    convertible to the other.  The ``enable_if_interoperable``
    approach uses SFINAE to take the operators out of the overload
    set when the types are not interoperable.  The operators should
    behave *as-if* ``enable_if_interoperable`` were defined to be::
    
      template <bool, typename> enable_if_interoperable_impl
      {};
    
      template <typename T> enable_if_interoperable_impl<true,T>
      { typedef T type; };
    
      template<typename Dr1, typename Dr2, typename T>
      struct enable_if_interoperable
        : enable_if_interoperable_impl<
              is_convertible<Dr1,Dr2>::value || is_convertible<Dr2,Dr1>::value
            , T
          >
      {};

9.4 enable_if_convertible unspecified, conflicts with requires 
==============================================================

:Submitter: Pete Becker 
:Status: New 

In every place where enable_if_convertible is used it's used like
this (simplified)::

  template<class T>
  struct C
  {
    template<class T1>
    C(T1, enable_if_convertible<T1, T>::type* = 0);
  };

The idea being that this constructor won't compile if T1 isn't
convertible to T. As a result, the constructor won't be considered
as a possible overload when constructing from an object x where the
type of x isn't convertible to T. In addition, however, each of
these constructors has a requires clause that requires
convertibility, so the behavior of a program that attempts such a
construction is undefined. Seems like the enable_if_convertible
part is irrelevant, and should be removed.  There are two
problems. First, enable_if_convertible is never specified, so we
don't know what this is supposed to do. Second: we could reasonably
say that this overload should be disabled in certain cases or we
could reasonably say that behavior is undefined, but we can't say
both.

Thomas Witt writes that the goal of putting in
enable_if_convertible here is to make sure that a specific overload
doesn't interfere with the generic case except when that overload
makes sense. He agrees that what we currently have is deficient.
Dave Abrahams writes that there is no conflict with the requires
cause because the requires clause only takes effect when the
function is actually called. The presence of the constructor
signature can/will be detected by is_convertible without violating
the requires clause, and thus it makes a difference to disable
those constructor instantiations that would be disabled by
enable_if_convertible even if calling them invokes undefined
behavior.  There was more discussion on the reflector:
c++std-lib-12312, c++std-lib-12325, c++std-lib- 12330,
c++std-lib-12334, c++std-lib-12335, c++std-lib-12336,
c++std-lib-12338, c++std-lib- 12362.

:Proposed resolution: 
  Change:

    [*Note:* The ``enable_if_convertible<X,Y>::type`` expression
    used in this section is for exposition purposes. The converting
    constructors for specialized adaptors should be only be in an
    overload set provided that an object of type ``X`` is
    implicitly convertible to an object of type ``Y``.  The
    ``enable_if_convertible`` approach uses SFINAE to take the
    constructor out of the overload set when the types are not
    implicitly convertible.]
    
  To:

    The ``enable_if_convertible<X,Y>::type`` expression used in
    this section is for exposition purposes. The converting
    constructors for specialized adaptors should be only be in an
    overload set provided that an object of type ``X`` is
    implicitly convertible to an object of type ``Y``.  The
    signatures involving ``enable_if_convertible`` should behave
    *as-if* ``enable_if_convertible`` were defined to be::

      template <bool> enable_if_convertible_impl
      {};

      template <> enable_if_convertible_impl<true>
      { struct type; };

      template<typename From, typename To>
      struct enable_if_convertible
        : enable_if_convertible_impl<is_convertible<From,To>::value>
      {};

    If an expression other than the default argument is used to
    supply the value of a function parameter whose type is written
    in terms of ``enable_if_convertible``, the program is
    ill-formed, no diagnostic required.

    [*Note:* The ``enable_if_convertible`` approach uses SFINAE to
    take the constructor out of the overload set when the types are
    not implicitly convertible.  ]

9.5 iterator_adaptor has an extraneous 'bool' at the start of the template definition 
=====================================================================================

:Submitter: Pete Becker 
:Status: New 

The title says it all; this is probably just a typo. 

:Proposed resolution: Remove the 'bool'.

9.6 Name of private member shouldn't be normative 
=================================================

:Submitter: Pete Becker 
:Status: New 

iterator_adaptor has a private member named m_iterator. Presumably
this is for exposition only, since it's an implementation
detail. It needs to be marked as such.

:Proposed resolution: Mark the member ``m_iterator`` 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.

  In [lib.iterator.adaptor]

  Change::

    Base m_iterator;

  to::

    Base m_iterator; // exposition only


9.7 iterator_adaptor operations specifications are a bit inconsistent 
=====================================================================

:Submitter: Pete Becker 
:Status: New 

iterator_adpator() has a Requires clause, that Base must be default
constructible.  iterator_adaptor(Base) has no Requires clause,
although the Returns clause says that the Base member is copy
construced from the argument (this may actually be an oversight in
N1550, which doesn't require iterators to be copy constructible or
assignable).

:Proposed resolution: Add a requirements section for the template
  parameters of iterator_adaptor, and state that Base must be Copy
  Constructible and Assignable.

  N1550 does in fact include requirements for copy constructible
  and assignable in the requirements tables. To clarify, we've also
  added the requirements to the text.


9.8 Specialized adaptors text should be normative 
=================================================

:Submitter: Pete Becker 
:Status: New 

similar to 9.3, "Specialized Adaptors" has a note describing
enable_if_convertible. This should be normative text.

:Proposed resolution: Changed it to normative
  text.  See the resolution of 9.4

9.9 Reverse_iterator text is too informal 
=========================================

:Submitter: Pete Becker 
:Status: New 

reverse iterator "flips the direction of the base iterator's
motion". This needs to be more formal, as in the current
standard. Something like: "iterates through the controlled sequence
in the opposite direction"

:Proposed resolution:

  Change:

    The reverse iterator adaptor flips the direction of a base
    iterator's motion. Invoking ``operator++()`` moves the base
    iterator backward and invoking ``operator--()`` moves the base
    iterator forward.

  to:

    The reverse iterator adaptor iterates through the adapted iterator
    range in the opposite direction.


9.10 'prior' is undefined 
=========================

:Submitter: Pete Becker 
:Status: New 

reverse_iterator::dereference is specified as calling a function
named 'prior' which has no specification.

:Proposed resolution:
  Change the specification to avoid using ``prior`` as follows.

  Remove::

    typename reverse_iterator::reference dereference() const { return *prior(this->base()); }

  And at the end of the operations section add:

    ``reference operator*() const;``

    :Effects: 

    ::

        Iterator tmp = m_iterator;
        return *--tmp;

:Rationale:
  The style of specification has changed because of issue 9.37x.



9.11 "In other words" is bad wording 
====================================

:Submitter: Pete Becker 
:Status: New 

Transform iterator has a two-part specification: it does this, in
other words, it does that. "In other words" always means "I didn't
say it right, so I'll try again." We need to say it once.

:Proposed resolution:
  Change:

    The transform iterator adapts an iterator by applying some function
    object to the result of dereferencing the iterator. In other words,
    the ``operator*`` of the transform iterator first dereferences the

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -