Skip to content

Last updated:2026-10-12

STL string deep dive

When we use C++, we are fairly familiar with the basics of the library, especially std::string, which is used to create strings in C++. This is undoubtedly an improvement over the old C-style “strings” (character arrays terminated with a null character). However, the C++ standard library introduced more useful components in C++17 and C++20 that can help you write more efficient code.

In the header, the std::basic_string class is a template class that provides specializations for various string types, including std::string for common strings (i.e. std::basic_string) and std::wstring for wide strings (i.e. std::basic_string).

There are also fixed-width specific strings, such as std::u32string (i.e. std::basic_string) and std::u16string (i.e. std::basic_string).

In C++20, char8_t was introduced, which also brought std::u8string (i.e. std::basic_string). I don't know why we had to wait until C++20 for char8_t, so let me ask a question: which standard introduced char16_t and char32_t? See you in the comments

C++11

Under the C++11 standard, string handling relies mainly on the std::string class, a dynamically memory-allocated string class. In addition, new fixed-width string types such as std::u32string and std::u16string were introduced, providing better support for handling Unicode characters.

#include <iostream>
#include <string>

int main() {
    // 使用std::string
    std::string str = "Hello, C++11!";

    // 使用std::u32string和std::u16string
    std::u32string u32str = U"Hello, Unicode!";
    std::u16string u16str = u"Hello, Unicode!";

    std::cout << str << std::endl;
    std::wcout << u32str << std::endl;
    std::wcout << u16str << std::endl;

    return 0;
}

C++17

In C++17, the header was introduced, providing a lightweight read-only alternative to using the string types from the header. These string views are similar to the strings described previously. For example, the equivalent of std::u32string is std::u32string_view (i.e. std::basic_string_view).

This is particularly useful in functions that need to read a string but not modify it. Instead of creating a copy of the string for the function, we can simply take a view of an existing string! Moreover, is very flexible: not only can C++-style strings be converted to string views, even C-style strings can be converted to string views. Here is an example demonstrating simple usage of std::string_view:

#include <iostream>
#include <string>
#include <string_view>

void printString(std::string_view str) {
  std::cout << str << std::endl;
}

int main() {
  std::string_view strv{"strv"}; // C++ string_view
  printString(strv);

  std::string str{"str"}; // C++ string
  printString(str);

  char cstr[] = "cstr"; // C-style string
  printString(cstr);

  return 0;
}

Output:

strv
str
cstr

In this example, the printString function takes a std::string_view as its parameter, which makes this function very lightweight and flexible, because no copies of any string are made; the function can be used in all sorts of ways by passing both C- and C++-style strings.

C++20

In C++20, several new and useful member functions were introduced, including starts_with(…) and ends_with(…). As the names suggest, these functions determine whether a string (or string view) starts/ends with a certain character or a certain std::string_view. Here is a simple example:

#include <cassert>
#include <string>
#include <string_view>

int main() {
  const std::string str{"Hello World!"};

  assert(str.starts_with('H'));
  assert(str.ends_with('!'));

  assert(str.starts_with("Hello")); // 隐式转换为std::string_view
  assert(str.ends_with("World!")); // 隐式转换为std::string_view

  return 0;
}

C++23

C++23 introduced contains, used to check whether a string contains a specified substring.

// 这是一个假设的C++23示例,实际上并不可用
#include <iostream>
#include <string>

int main() {
    std::string str = "C++23 introduces contains function.";

    if (str.contains("introduces")) {
        std::cout << "The string contains 'introduces'." << std::endl;
    } else {
        std::cout << "The string does not contain 'introduces'." << std::endl;
    }

    return 0;
}

https://en.cppreference.com/w/cpp/string/basic_string/contains

Conclusion

When working with strings in new C++ code, you should aim to make the code as flexible and memory-efficient as possible. Using can greatly help with these efforts. In addition, consider using the latest string member functions such as starts_with and ends_with to get readable and easy-to-implement string parsing code. And C++23 makes the contains check even simpler — things keep getting more modern.

Comments