reverse_iterator
and move_iterator
Section: 24.5.1.6 [reverse.iter.elem], 24.5.4.6 [move.iter.elem] Status: NAD Submitter: Alisdair Meredith Opened: 2009-03-12 Last modified: 2021-06-06
Priority: Not Prioritized
View all other issues in [reverse.iter.elem].
View all issues with NAD status.
Discussion:
Addresses UK 279 [CD1]
The reason the return type became unspecified is LWG issue 386. This reasoning no longer applies as there are at least two ways to get the right return type with the new language facilities added since the previous standard.
Proposal: Specify the return type using either decltype or the Iter concept_map.
[ Summit: ]
Under discussion. This is a general question about all iterator adapters.
[ Howard adds post Summit: ]
I am requesting test cases to demonstrate a position.
[ 2009-07-24 Daniel adds: ]
I recommend NAD. Without concepts we can no longer restrict this member in a trivial way. Using
decltype
the declaration would be along the lines ofstatic const Iter& __base(); // not defined auto operator[](difference_type n) const -> decltype(__base()[-n-1]);but once
reverse_iterator
is instantiated for some given typeIter
which cannot form a well-formed expression__base()[-n-1]
this would cause an ill-formed function declaration, diagnostic required, and no silent SFINAE elimination.
[ 2009-10 Santa Cruz: ]
Moved to NAD.
[ 2009-10-22 Daniel adds: ]
IMO, my original comment regarding ill-formedness of the described construction is still correct, but I must add that I should weaken my assertion "Without concepts we can no longer restrict this member in a trivial way".
In fact with the existence of default template arguments for function templates it is not too hard to implement this like as follows, which shows that we can indeed simulate to some sense constrained member functions in C++0x.
My example does not really proof that the specification is easy, but it should be possible. I assume that the implementation would not be ABI compatible, though.
It is now your own decision how to proceed ;-)
#include <type_traits> #include <cstddef> template<class T> typename std::add_rvalue_reference<T>::type declval(); template<class It> struct reverse_iterator { It base; typedef std::ptrdiff_t difference_type; template<class U = It, class Res = decltype(declval<const U&>()[declval<difference_type>()]) > Res operator[](difference_type n) const { return base[-n-1]; } }; struct MyIter { }; int main() { reverse_iterator<int*> ri; ri[0] = 2; reverse_iterator<MyIter> ri2; }The above declaration could be simplified, but the ideal solution
template<class U = It> decltype(declval<const U&>()[declval<difference_type>()]) operator[](difference_type n) const;does not work yet on gcc 4.4.1.
Proposed resolution: