Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why can't I create a std::string_view from std::string iterators?

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?

like image 599
Const Avatar asked Aug 27 '21 13:08

Const


People also ask

Is it possible to deal with constant strings with std::string?

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:

Why use string_view instead of 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.

Do I need to call the string_view constructor in C++?

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&.

Is it safe to use string views in C++?

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.


Video Answer


2 Answers

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 };
}
like image 58
Caleth Avatar answered Oct 23 '22 16:10

Caleth


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};
like image 42
eerorika Avatar answered Oct 23 '22 14:10

eerorika