Topic: const_reverse_iterator


Author: Ralf Stoffels <stoffels@faho.rwth-aachen.de>
Date: 1997/08/11
Raw View
A Container::const_reverse_iterator is a little bit annoying to use,
because a Container::reverse_iterator is not convertable to a
Container::const_reverse_iterator.

So this here is not correct:
vector<int> v;
for(vector<int>::const_reverse_iterator v.rbegin();
    i != v.rend(); ++i);

You have to write:
for(vector<int>::const_reverse_iterator
 i = (const_cast<const vector<int>&>(v)).rbegin();
 i != (const_cast<const vector<int>&>(v)).rend(); ++i);


I think this template constructor in reverse_iterator<Iterator>
would fix the problem:
template<_Iterator>
explicit reverse_iterator(const reverse_iterator<_Iterator>&  x)
         : current(x.base()) {}

Note that this is not a copy constructor because it is a template
contructor.


Ralf Stoffels
---
[ comp.std.c++ is moderated.  To submit articles: try just posting with      ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu         ]
[ FAQ:      http://reality.sgi.com/employees/austern_mti/std-c++/faq.html    ]
[ Policy:   http://reality.sgi.com/employees/austern_mti/std-c++/policy.html ]
[ Comments? mailto:std-c++-request@ncar.ucar.edu                             ]





Author: fjh@mundook.cs.mu.OZ.AU (Fergus Henderson)
Date: 1997/08/12
Raw View
Ralf Stoffels <stoffels@faho.rwth-aachen.de> writes:

>A Container::const_reverse_iterator is a little bit annoying to use,
>because a Container::reverse_iterator is not convertable to a
>Container::const_reverse_iterator.
>
>So this here is not correct:
>vector<int> v;
>for(vector<int>::const_reverse_iterator v.rbegin();
>    i != v.rend(); ++i);
>
>You have to write:
>for(vector<int>::const_reverse_iterator
> i = (const_cast<const vector<int>&>(v)).rbegin();
> i != (const_cast<const vector<int>&>(v)).rend(); ++i);

That is bad coding style, IMHO, because you should use
`implicit_cast' (a.k.a. `implicit_conversion', `convert', or `safe_cast')
rather than `const_cast' for the cases that are adding const,
rather than removing it.

It is a pity that the C++ draft standard does not include
`implicit_cast' or something like it, because that lack will
continue to encourage such misuses of `const_cast'.

--
Fergus Henderson <fjh@cs.mu.oz.au>   |  "I have always known that the pursuit
WWW: <http://www.cs.mu.oz.au/~fjh>   |  of excellence is a lethal habit"
PGP: finger fjh@128.250.37.3         |     -- the last words of T. S. Garp.
---
[ comp.std.c++ is moderated.  To submit articles: try just posting with      ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu         ]
[ FAQ:      http://reality.sgi.com/employees/austern_mti/std-c++/faq.html    ]
[ Policy:   http://reality.sgi.com/employees/austern_mti/std-c++/policy.html ]
[ Comments? mailto:std-c++-request@ncar.ucar.edu                             ]





Author: Ralf Stoffels <stoffels@faho.rwth-aachen.de>
Date: 1997/08/12
Raw View
Fergus Henderson wrote:
> >for(vector<int>::const_reverse_iterator
> > i = (const_cast<const vector<int>&>(v)).rbegin();
> > i != (const_cast<const vector<int>&>(v)).rend(); ++i);
>
> That is bad coding style, IMHO, because you should use
This is only an example to demonstrate that it is not possible to use a
const_reverse_iterator as expected.
> `implicit_cast' (a.k.a. `implicit_conversion', `convert', or `safe_cast')
> rather than `const_cast' for the cases that are adding const,
> rather than removing it.
So what coding style would you suggest (based on the current DWP) ?
Of course you can use a separate const vector reference, but this does
not really correspond to the non-reverse iterator style.

> It is a pity that the C++ draft standard does not include
> `implicit_cast' or something like it, because that lack will
> continue to encourage such misuses of `const_cast'.


But what do think about the more interesting part of my posting,
the template constructor which would fix the problem ?


It is the same problem as in <complex>:
to allow the conversion from complex<float> to complex<double> there is
template<T> template<class X> complex<T>::complex(const complex<X>&);


Ralf
---
[ comp.std.c++ is moderated.  To submit articles: Try just posting with your
                newsreader.  If that fails, use mailto:std-c++@ncar.ucar.edu
  comp.std.c++ FAQ: http://reality.sgi.com/austern/std-c++/faq.html
  Moderation policy: http://reality.sgi.com/austern/std-c++/policy.html
  Comments? mailto:std-c++-request@ncar.ucar.edu
]





Author: Ralf Stoffels <stoffels@faho.rwth-aachen.de>
Date: 1997/08/14
Raw View
> vector<int> v;
> for(vector<int>::const_reverse_iterator i = v.rbegin();
>     i != v.rend(); ++i);
>
> You have to write:
> for(vector<int>::const_reverse_iterator
>  i = (const_cast<const vector<int>&>(v)).rbegin();
>  i != (const_cast<const vector<int>&>(v)).rend(); ++i);
>
> I think this template constructor in reverse_iterator<Iterator>
> would fix the problem:
> template <class _Iterator>
> explicit reverse_iterator(const reverse_iterator<_Iterator>&  x)
>          : current(x.base()) {}

Oh, there is a problem with this explicit constructor:
for(vector<int>::const_reverse_iterator i = v.rbegin(); ...
is fine, but instead of
i != v.rend();
you would have to write
i != vector<int>::const_reverse_iterator(v.rend());

An implicit constructor would fix this problem, too.
template <class _Iterator>
  reverse_iterator(const reverse_iterator<_Iterator>&  x)
          : current(x.base()) {}

Does anyone see problems with the rest of the standard, which would be
induced by this implicit or explicit constructor ?


Ralf
---
[ comp.std.c++ is moderated.  To submit articles: try just posting with      ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu         ]
[ FAQ:      http://reality.sgi.com/employees/austern_mti/std-c++/faq.html    ]
[ Policy:   http://reality.sgi.com/employees/austern_mti/std-c++/policy.html ]
[ Comments? mailto:std-c++-request@ncar.ucar.edu                             ]





Author: Ralf Stoffels <stoffels@faho.rwth-aachen.de>
Date: 1997/08/14
Raw View
> It is the same problem as in <complex>:
> to allow the conversion from complex<float> to complex<double> there is
> template<T> template<class X> complex<T>::complex(const complex<X>&);

This not entirely correct.
This implicit constructor allows e.g. the conversion from complex<float>
to complex<int>.
For the conversion from complex<float> to complex<double> there is a
specialized implicit constructor.


Ralf
---
[ comp.std.c++ is moderated.  To submit articles: try just posting with      ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu         ]
[ FAQ:      http://reality.sgi.com/employees/austern_mti/std-c++/faq.html    ]
[ Policy:   http://reality.sgi.com/employees/austern_mti/std-c++/policy.html ]
[ Comments? mailto:std-c++-request@ncar.ucar.edu                             ]