Last updated:2026-10-12
C++17 std::string_view¶
0.The problem¶
string_view was introduced after C++17; it is essentially the slice in leveldb, and its purpose is to solve memory copying and provide an efficient substr.
However, it also introduces problems with pointers and references. Since a string_view does not own the content it points to, compared with Rust it is merely a borrow: if the object that owns the content is released early, a dangling reference problem arises. Rust analyzes variable lifetimes at compile time to guarantee that borrowed resources are not released while still in use. C++, however, performs no such checking, so it must be guaranteed manually.
1.Internal implementation¶
string_view is a basic_string_view type. As you can see, _Traits uses the default char_traits, which is important: several of the functions below rely on member functions of char_traits to perform their core operations.
template<class _CharT, class _Traits = char_traits<_CharT> >
class _LIBCPP_TEMPLATE_VIS basic_string_view;
typedef basic_string_view<char> string_view;
Members of basic_string_view:
Construction is compatible with string and const char*:
constexpr basic_string_view() noexcept;
constexpr basic_string_view(const basic_string_view&) noexcept = default;
basic_string_view& operator=(const basic_string_view&) noexcept = default;
template<class Allocator>
constexpr basic_string_view(const charT* str);
constexpr basic_string_view(const charT* str, size_type len);
Iterator support:
constexpr const_iterator begin() const noexcept;
constexpr const_iterator end() const noexcept;
constexpr const_iterator cbegin() const noexcept;
constexpr const_iterator cend() const noexcept;
const_reverse_iterator rbegin() const noexcept;
const_reverse_iterator rend() const noexcept;
const_reverse_iterator crbegin() const noexcept;
const_reverse_iterator crend() const noexcept;
Other core functions:
- substr
- remove_prefix
- compare
- find
- ...
Since C++20 it also supports starts_with, ends_with, and contains; these three were supported in leveldb's slice from the very beginning.
A string_view literal for char*:
constexpr basic_string_view<char> operator "" sv( const char *str, size_t len ) noexcept;
constexpr basic_string_view<wchar_t> operator "" sv( const wchar_t *str, size_t len ) noexcept;
constexpr basic_string_view<char16_t> operator "" sv( const char16_t *str, size_t len ) noexcept;
constexpr basic_string_view<char32_t> operator "" sv( const char32_t *str, size_t len ) noexcept;
2.Pitfalls in use¶
2.1 \0¶
string_view does not care about \0; it cares about the actual number of characters.
Output: s: 8 "abcdef"
Here hello is expected to be printed, but h is printed instead.
2.2 Lifetime¶
In this example, once s goes out of scope, the string_view becomes a dangling reference.
Lifetime
std::string_view does not own the underlying character storage; make sure the lifetime of the referenced object covers the entire period of use.
Related Topics¶
- C++17 [[nodiscard]] Attribute | C++那些事
- C++17 PMR Memory Resources | C++那些事
- C++17 Seventeen Advanced Features | C++那些事
- C++17 Class Template Argument Deduction CTAD | C++那些事
- C++17 optional_ref | C++那些事
- C++17 std::variant | C++那些事
- C++17 Structured Bindings | C++那些事
- C++17 Template auto Deduction | C++那些事
- C++17 Variable Templates | C++那些事