Comparison of C++ String Classes: std::string andstd::string_view

Generally, std::string_view is the replacement for std::string when you don't own the string.

If a function parameter is a const string& (a constant reference), you should prefer to change it to string_view (by value), as you don't own the argument.

string_view is best in this case because it doesn't require an actual std::string to exist. Just a sequence of characters. In particular, if you do this:

std::string_view v{"this string is too long for small-buffer optimization\n"};

then there is no memory allocation - a performance benefit.

>
std::string std::string_view
Nature A container of characters A reference to a run of characters (in memory)
Explicit literals s suffix in namespace std::string_literals sv suffix in namespace std::string_view_literals
Assignment (operator=) and copy constructor deep (copy) shallow (copy)
bool contains(STRING_VIEW) bool contains(STRING_VIEW)
bool starts_with(STRING_VIEW) bool starts_with(STRING_VIEW)
bool ends_with(STRING_VIEW) bool ends_with(STRING_VIEW)
Implicit conversion/constructor implicitly converts to a std::string_view implicitly converts to a std::string_view
Substrings
constexpr basic_string
    substr( size_type pos = 0, size_type count = npos ) const&;
	(since C++23)
constexpr basic_string substr( size_type pos = 0, size_type count = npos ) &&;
constexpr string substr (size_type pos = 0, size_type count = npos) const
Get underlying C-string
const charT* c_str() const noexcept;
(const) charT* data() const noexcept;
constexpr const_pointer data() const noexcept;
Capacity (same) empty(), size() or length(), and max_size() (returns the maximum number of characters)
Book some memory or return size of allocated storage (only std::string) reserve(size_type n)
capacity()
Swap constexpr void swap( basic_string& other ) noexcept; constexpr void swap( basic_string_view& v ) noexcept;
Modifiers (only std::string) clear(), insert(...), insert_range(...) (C++23), erase(...), push_back(CHAR), pop_back(), append(...), append_range(...) (C++23), operator+=(...), replace(...), replace_with_range(...) (C++23), copy(...)
Change boundaries (start or end)

resize(size_type sz)

template <class Operation> constexpr void resize_and_overwrite( size_type count, Operation op) (C++23) (changes the number of characters stored and possibly overwrites indeterminate contents via user-provided operation)

remove_prefix(size_type n)
remove_suffix(size_type n)
Last / Terminating character Always null-terminated. May or may not be null-terminated.
Comparison compare(const string& s) compare(string_view sv)
constexpr basic_string_view substr(
size_type pos = 0,
size_type count = npos ) const;
No position. string::npos
static constexpr size_type npos = size_type(-1);

This is a special value equal to the maximum value representable by the type size_type. The exact meaning depends on context, but it is generally used either as end of view indicator by the functions that expect a view index or as the error/failure indicator by the functions that return a view index.

Where is to be found, if anywhere? find* and rfind find* and rfind
Find the first substring equal to the given character sequence
constexpr size_type find( const basic_string& str, size_type pos = 0 ) const;
constexpr size_type find( const CharT* s, size_type pos, size_type count ) const;
constexpr size_type find( const CharT* s, size_type pos = 0 ) const;
constexpr size_type find( CharT ch, size_type pos = 0 ) const;
constexpr size_type find( basic_string_view v, size_type pos = 0 ) const noexcept;
constexpr size_type find( const CharT* s, size_type pos, size_type count ) const;
constexpr size_type find( const CharT* s, size_type pos = 0 ) const;
constexpr size_type find( CharT ch, size_type pos = 0 ) const noexcept;
Element access: operator[](idx), at(idx) (accesses the specified character with bounds checking), front(), back(), data() operator[](idx), at(idx) (accesses the specified character with bounds checking), front(), back(), data()