C++ Weekly #1: std::string_view

What’s a string_view, and Why Should We Use?

Def.

The class template basic_string_view describes an object that can refer to a constant contiguous sequence of char-like objects with the first element of the sequence at position zero.

A typical implementation holds only two members: a pointer to constant CharT and a size.

Based on the definition from cppreference, we see that string_view should allocate no memory when using it.

Compare

When we have function take a const string as an argument, we have three alternatives: C char* style, C++ string style and c++17 string_view style.

void c_style(const char* s);                        //  C convention
void cpp_string_style(const std::string& s);        //  Old standard C++ convention
void cpp17_string_view_style(std::string_view sv);  //  C++17 convention

The first two case works fine when a caller passes the string in the given format, but it required a conversion when the format is different ( const char* to std::string and std::string to const char*).

  • convert a std::string to const char*: use c_str() function (efficient but inconvenient)
    void already_has_string(const std::string& s) {
      take_char_star(s.c_str());      //  explicit conversion
    }
    
  • convert a const char* to std::string: implicit conversion(convenient but inefficient). This will result in a copy of the content by creating a temporary string.
    void already_has_char_star(const char* s) {
      take_string(s);                 //  implicit conversion, compiler will make a copy
    }
    

How to Fix the Issue?

In c++17, Standard C++ provides us this new tool to handle the above situation. We don’t have to basically write the same function twice but take different string formats for the performance fix. Besides that, we could also remain convenient at the same time by passing either const char* or std::string to std::string_view.

  void already_has_string(const std::string& s) {
    take_string_view(s);      //  no explicit conversion (convenient)
  }

  void already_has_char_star(const char* s) {
    take_string_view(s);      //  no copy (efficient)
  }

IMPORTANT: Since std::string_view does not own the data, make sure your data pointed to by the std::string_view need have a longer lifetime.

Summary

  • No memory allocation required (even better than Small String Optimization!)
  • Other benefits! (not mentioned in this post, but you can check it out yourself)
    • Efficient substr() method

      O(1) for std::string_view, compare to O(n) for std::string

    • All the other goody when doing string parse

      build-in remove_prefix(), remove_suffix() member functions and so on.

Xuhui Sun
Xuhui Sun
Senior Software Engineer

Modern C++ enthusiast exploring Artificial Intelligence and Machine Learning. Passion for learning and sharing knowledge! ❤️