Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

using const_reverse_iterator = reverse_iterator<const_iterator>; #6053

Open
notbob-at-tessellation-com opened this issue Jan 18, 2023 · 3 comments

Comments

@notbob-at-tessellation-com

Hello,

Today I am making my first posts to this group. Please forgive me if I make mistakes. Thank you.

Here is the context:

Header <string_view>:

template<class charT, class traits = char_traits>
class basic_string_view {
public:
// types
using traits_type = traits;
using value_type = charT;
using pointer = value_type*;
using const_pointer = const value_type*;
using reference = value_type&;
using const_reference = const value_type&;
using const_iterator = implementation-defined ; // see 24.4.2.2
using iterator = const_iterator;228
using const_reverse_iterator = reverse_iterator<const_iterator>;
using reverse_iterator = const_reverse_iterator;

I understand that the alias declaration for const_reverse_iterator uses the only declaration of reverse_iterator that is in scope at that moment, which is std::reverse_iterator, but then reverse_iterator is defined again on the next line, which creates an ordering dependency. Wouldn't it be safer and clearer to say:

using const_reverse_iterator = std::reverse_iterator<const_iterator>;
using reverse_iterator = const_reverse_iterator;

or even:

using const_reverse_iterator = std::reverse_iterator<const_iterator>;
using reverse_iterator = std::reverse_iterator<const_iterator>;

as they end up being the same type anyway, and this would eliminate the ordering issue?

Thank you,

Robert Schwartz

@jwakely
Copy link
Member

jwakely commented Jan 18, 2023

Yes, we should use std::reverse_iterator here. I don't think we should change the definition of reverse_iterator though, it's clearer to show that it's the same type as const_reverse_iterator by defining it to be exactly that, not by defining them separately to the same type.

@notbob-at-tessellation-com
Copy link
Author

@Quuxplusone
Copy link
Contributor

Quuxplusone commented Jan 18, 2023

A quick git grep 'reverse_iterator *=' source/ shows that [string.view] is the only section that uses the inconsistent style. Everyone else does the same thing (NB: even set, whose iterators and const_iterators are the same type):

source/containers.tex:    using reverse_iterator       = std::reverse_iterator<iterator>;
source/containers.tex:    using const_reverse_iterator = std::reverse_iterator<const_iterator>;

Except for [span], which does it the other way around:

source/containers.tex:    using reverse_iterator = std::reverse_iterator<iterator>;
source/containers.tex:    using const_reverse_iterator = std::const_iterator<reverse_iterator>;

That looks like a typo, but in fact it was intentional: 3253518 implements @brevzin's P2278R4 "cbegin should always return a constant iterator", which has a whole section admitting that this is confusing but done intentionally so that span.crbegin() and ranges::crbegin(span) have the same type. There's no discussion there of why we care about those types being identical but not, say, the types of vector.crbegin() and ranges::crbegin(vector).

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants