std::string vs. std::string_view

In both passing as a parameter, and as both a plain data type. When to use which?

For the longest time I've always passed strings as a const ref:
 
Window(const std::string& title, int w, int h);


But now that I'm learning about std::string_view. I'm wondering if one should prefer passing a std::string_view over a const ref std::string:
 
Window(const std::string_view title, int w, in h);



So that's just passing a string type as a parameter, What do you think?
Next I want to talk about a string type as just a normal member variable.

Which one of these would you prefer for a normal member variable string type?
 
std::string m_title;


 
std::string_view m_title;


 
const char* m_title;


is string_view a better replacement for a const char* member variable type when used, or even a normal std::string member variable? Or one would prefer to use std::string_view over const char* rather than prefer std::string_view over std::string when talking about normal member variables.
Last edited on
But now that I'm learning about std::string_view. I'm wondering if one should prefer passing a std::string_view over a const ref std::string:

Yes.

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.

If the function parameter is a const string&, you should prefer to change it to string_view: you don't own the argument.

If you do own the string, then std::string alone is the only decent choice. In the case of your class, the window probably owns its title, and so the member should just be a string.

If the window doesn't own its title, use string_view. Note that const char* was never an option, because a std::string may contain zero bytes (zero byte as in '\0') in the middle. This means that unless you record the size, you can't always retrieve the original string.

string_view is best in this case because it doesn't require an actual std::string to exist. Just a sequence of char. In particular, if you do this:
std::string_view v{"this string is too long for small-buffer optimization\n"};
There is no memory allocation - a performance benefit.

We might also consider std::string const* and std::string const&), but they require a string to exist. If you pair char const* and a size, you've got something that works, just less useful and more dangerous.
Last edited on
> I'm wondering if one should prefer passing a std::string_view over a const ref std::string:

In general, yes. Doing so offers more flexibility (the view need not necessarily be of an underlying std::string) and in many cases better performance(avoid construction of objects of type std::string)

The string view does not own the underlying sequence of characters; so one has to be careful about keeping copies of string views or returning a string view from the function.

For instance:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
#include <iostream>
#include <string>
#include <string_view>
#include <algorithm>

std::string_view trim( std::string_view str )
{
    str.remove_prefix( std::min( str.find_first_not_of( ' ' ), str.size() ) ) ;
    const auto pos = str.find_last_not_of( ' ' ) ;
    if( pos != str.npos ) str.remove_suffix( str.size() - pos - 1 ) ;
    return str ;
}

int main()
{
    std::cout << '"' << trim( "   hello world!   " ) << "\"\n" ; // fine
    const auto sv = trim( "   hello world!   " ) ; // fine
    std::cout << '"' << sv << "\"\n" ; // fine
    
    using namespace std::literals ;
    
    std::cout << '"' << trim( "   hello world!   "s ) << "\"\n" ; // fine

    const auto sv2 = trim( "   hello world!   "s ) ; // *** logical error ***
    std::cout << '"' << sv2 << "\"\n" ; // *** undefined behaviour ***
}
Last edited on
@JLBorges Appreciate that information and example. The more I learn, the more I realize how much I still have to learn, hah. Thanks again.

You as well @mbozzi
Last edited on
std::string_view is only available with C++17
For people who have to use older compilers there is a standalone string_view for C++11 at https://github.com/bitwizeshift/string_view-standalone
Also, boost::string_view.
Topic archived. No new replies allowed.