std::string or std::string_view

Hi all,

I found this interesting thread:
http://www.cplusplus.com/forum/beginner/240488/#msg1070623

where mbozzi said:
Really, the choice depends on the semantics of the function and the class you're defining, but in general: std::string_view is the replacement for std::string when you don't own the string.

So if our class/function owns the string we must use std::string over std::string_view, and the other way around when that class/function doesn't own the string. I'm not sure what owning means here. Will you explain it a little more or give an example?

Last edited on
string_view contains a pointer to existing, initialised memory and a size. Whilst a string_view variable is being used, the underlying memory referenced must be valid. The string_view variable doesn't own the data and can't change it. But for read-only functions (eg find et al), it is light weight and fast as it has virtually no overhead (as string does). As it only has the pointer/size elements, creating one and copying one is fast with minimal overhead - so passing by value is OK. It can be created from a string, a string_view and a c-style char array. NOTE that it is
not
guaranteed to be null-terminated and so can't be passed to any function which requires a null-terminated string (string.c_str() returns null-terminated, but there's no equivalent for string_view).

There are some current limitations - such as not using a string_view to initialise a istringstream, using for a file name etc.

owning here simply means who is responsible for deleting/modifyig the data. If you pass string by value, you get a copy which is owned by who created the copy. If you pass by const ref, then the ownership remains with the original. string_view doesn't 'own' the underlying data - the original user still does.

The important point about string_view is that the original data must still be valid (owned) by the owner whilst the string_view is being used. This is of particular importance for 'temporary' data (rvalue) which isn't valid after it's duration.

> string_view contains a pointer to existing, initialised memory and a size

The standard does not specify that; the private members of std::string_view are marked // exposition only
This means that while this is a possible implementation, it need not be the only possible implementation.

For instance, an implementation that internally contains two pointers would be a conforming implementation.

if you are doing some kind of ugly C-string work, you can do this:
stringvar += '\0' (and THEN take your view into it)
and then c-string tools will work on it.
Not normally recommended but some hardware and interfaces still use char* a lot. The extra character will be exposed; on most consoles it functions a lot like a trailing space character and in other places may display a funky placeholder character. Use with caution, if you use it at all. Not sure why you would need it here (I see no reason, and that makes it a poor choice).
Last edited on
> if you are doing some kind of ugly C-string work, you can do this:
> stringvar += '\0' (and THEN take your view into it)

This is quite unnecessary; std::string always holds a null character at the very end, after the last character.

1
2
3
4
5
6
7
8
9
10
11
#include <iostream>
#include <string>
#include <string_view>

int main()
{
    const std::string str = "abcdefgh" ;
    std::string_view sv = str ; // the null character is there, but it is not part of the view
    std::string_view sv_cstr( str.data(), str.size()+1 ) ; // the null character is part of the view
    std::cout << sv.size() << ' ' << sv_cstr.size() << '\n' ; // 8 9
}

http://coliru.stacked-crooked.com/a/4b6beb5da9ca9fcc
@seeplus

So for anything that's using an std::string_view we must pay enough attention into account that the view string is just being read not edited etc, so attempts to do these modifying actions face failure.

But for read-only functions (eg find et al), it is light weight and fast
Doesn't find compare the view with the string values of the container it's traversing? Do they match!?

As well as, if possible, express some more examples where we can use that string view, please.
Hah, nice one. I just mentally assumed that +1 was out of bounds and never really checked it.
> So for anything that's using an std::string_view we must pay enough attention into account
> that the view string is just being read. But for read-only functions (eg find et al), it is light weight and fast


std::span<>() (C++20) gives us a (possibly mutable) view of a contiguous sequence of objects of any type.
https://en.cppreference.com/w/cpp/container/span

1
2
3
4
5
6
7
8
9
10
11
12
13
14
#include <iostream>
#include <span>
#include <locale>

int main()
{
    std::string str = "abcdefgh" ;
    std::cout << str << '\n' ; // abcdefgh

    std::span span( str.begin(), str.end() ) ;
    for( char& c : span ) c = std::toupper( c, std::cout.getloc() ) ; 

    std::cout << str << '\n' ; // ABCDEFGH
}

http://coliru.stacked-crooked.com/a/926dbd942c8b8ae4
Topic archived. No new replies allowed.