It is possible to create a std::string_view
from a std::string
easily. But if I want to create a string view of a range of std::string
using the iterators of the std::string
does not work.
Here is the code that I tried: https://gcc.godbolt.org/z/xrodd8PMq
#include <iostream>
#include <string>
#include <string_view>
#include <iterator>
int main()
{
std::string str{"My String"};
std::string_view strView{str}; // works
//std::string_view strSubView{str.begin(), str.begin() + 2}; // error
}
Of course maybe we can make the substring out from str
and use to make a string view strSubView
, but there is an extra string creation.
I found that the std::basic_string_view
s fifth constructor takes the range of iterators.
template<class It, class End>
constexpr basic_string_view(It first, End last);
But is it only the iterators of the std::string
or just std::basic_string_view
's itself? If not for std::string
's iterates why shouldn't be we have one, after all the string view:
describes an object that can refer to a constant contiguous sequence of char-like objects !
Taking the range of contiguous sequence of char, should not we count?
The std::string has some demerits, one of the most common situations is constant strings. Below is the program that demonstrates the problem that occurs in dealing with constant strings with std::string:
This means a string_view can often avoid copies, without having to deal with raw pointers. In modern code, std::string_view should replace nearly all uses of const std::string& function parameters. This should be a source-compatible change, since std::string declares a conversion operator to std::string_view.
Ultimately you should never need to call the std::string_view constructor like you are. std::string has a conversion operator that handles the conversion automatically. A std::string_view brings some of the benefits of a const char* to C++: unlike std::string, a string_view has one less level of pointer indirection than a std::string&.
Just because a string view doesn't help in your specific use case where you need to create a string anyway does not mean that it's a bad idea in general. The C++ standard library tends to be optimized for generality rather than for convenience. The “less safe” argument doesn't hold, as it shouldn't be necessary to create the string view yourself.
That constructor is added in C++20. If you are compiling with a C++17 compiler then it isn't present.
You can write a function that does the same thing
std::string_view range_to_view(std::string::iterator first, std::string::iterator last) {
return first != last ? { first.operator->(), last - first } : { nullptr, 0 };
}
Why can not I create a std::string_view from std::string itertors?
You can, but only since C++20.
But is it only the iterators of the std::string or just std::basic_string_view 's itself?
It's any contiguous iterators of appropriate value type. Both string and string view iterators are accepted. The exact constraints are listed in the documentation.
That means in C++17 there is no way to do it??
There's no way to use a constructor that doesn't exist, but there are several ways of getting the string view that you want. Here's one:
std::string_view strSubView = strView.substr(0, 2);
or without the intermediate variable:
std::string_view strSubView = std::string_view{str}.substr(0, 2);
or if you only have those iterators and have no way of accessing the string:
std::string_view strSubView {&*first, last - first};
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With