Let's say that we have a string_view and another string_view that is a subset of the first string_view:
using namespace std; // just to shorten the example...
string_view s{"abc def"};
auto t = s.substr(4);
auto u = s.substr(0, 4);
cout << *(s.begin() + 4) << " " << *t.begin() << '\n';
cout << ((s.begin() + 4) == t.begin());
cout << (s.end() == t.end());
cout << ((s.begin() +5) == t.begin());
cout << ((s.begin() +5) == (t.begin() + 1));
cout << ((s.begin() + 4) == u.end()); // true
All the comparisons would work on Linux under gcc (9 HEAD) and clang (8 HEAD). Under Windows Visual c++ (15.7.6) the comparison of two iterators is not allowed (in debug mode you get an assert error cannot compare incompatible string_view iterators for equality
).
Next is pointer comparison:
string_view s{"abc def"};
char const*& it{...}; // contains pointer to some location in s
auto t = s.substr(4);
it == s.end(); // works in gcc/clang - fails to compile in Visual studio
So when you try to fix it in Visual C++ you want to compare addresses it == &*s.end()
but this fails as end()
iterator is not supposed to be dereferenced (UB if I remember correctly) so you get cannot dereference end string_view iterator
.
boost::string_view supports it == s.end()
comparison so I'm surprised that the std implementation is more limiting (and thereby far less user friendly for cross platform work)
I understand that iterator comparison of two different containers is UB but string_view is not a container (it doesn't own underlying memory) it's some form of a smart pointer so I would expect the language to allow me to compare such iterators trusting me that the views are pointing to a different (or same) subset of the same container.
So my question is how can I make something like this work with string_view only?
(Meaning without needing to create a custom range class that will contain two iterators as this would defeat the purpose of using std::string_view in the first place)
You appear to want to work with raw pointers.
If you want to work with raw pointers, use .data()
instead of .begin()
and .data()+.size()
instead of end()
.
These pointers behave like you want string view iterators to behave.
If you need iterators back, ptr-.data()+.begin()
reconstructs an iterator (and it-begin()+.data()
round trips back to ptr).
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.