Перейти к содержанию

Последнее обновление:2026-10-12

Глубокий анализ STL string

Работая с C++, мы хорошо знаем основы библиотеки , особенно std::string, используемый для создания строк в C++. Это, без сомнения, шаг вперёд по сравнению со старыми C-строками (массивами символов, завершающимися нулевым символом). Однако стандартная библиотека C++ в C++17 и C++20 ввела более полезные компоненты, которые помогут вам писать более эффективный код.

В заголовочном файле класс std::basic_string — это шаблонный класс, предоставляющий специализации для различных строковых типов, включая обычные строки std::string (то есть std::basic_string) и широкие строки std::wstring (то есть std::basic_string).

Есть также строки фиксированной ширины, например std::u32string (то есть std::basic_string) и std::u16string (то есть std::basic_string).

В C++20 появился char8_t, а вместе с ним и std::u8string (то есть std::basic_string). Не знаю, зачем пришлось ждать C++20 ради char8_t, поэтому задам вопрос: в каком стандарте появились char16_t и char32_t? до встречи в комментариях

C++11

В стандарте C++11 работа со строками опирается в основном на класс std::string — строковый класс с динамическим выделением памяти. Кроме того, были введены новые строковые типы фиксированной ширины, такие как std::u32string и std::u16string, обеспечившие лучшую поддержку символов Unicode.

#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

В C++17 появился заголовочный файл , предоставляющий легковесную альтернативу только для чтения строковым типам из заголовочного файла . Эти представления строк аналогичны описанным ранее строкам. Например, эквивалент для std::u32string — это std::u32string_view (то есть std::basic_string_view).

Это особенно полезно в функциях, которым нужно читать строку, но не изменять её. Вместо того чтобы создавать для функции копию строки, мы можем просто просмотреть существующую строку! Более того, очень гибок: в представление строки можно преобразовать не только C++-строку, но даже C-строку. Вот пример, демонстрирующий простое использование 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;
}

Вывод:

strv
str
cstr

В этом примере функция printString принимает std::string_view в качестве параметра, что делает её очень легковесной и гибкой: копии строки не создаются, а использовать функцию можно самыми разными способами, передавая C- и C++-строки.

C++20

В C++20 появились новые полезные функции-члены, включая starts_with(…) и ends_with(…). Как следует из названий, эти функции определяют, начинается ли / заканчивается ли строка (или представление строки) определённым символом или определённым std::string_view. Вот простой пример:

#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 появился contains, позволяющий проверять, содержит ли строка указанную подстроку.

// 这是一个假设的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

Заключение

Работая со строками в новом C++-коде, следует стремиться делать код максимально гибким и экономным по памяти. Использование очень помогает в этом. Кроме того, подумайте об использовании новейших строковых функций-членов, таких как starts_with и ends_with, чтобы получать читаемый и легко реализуемый код разбора строк. А C++23 делает проверку contains ещё проще — всё современнее и современнее.

Похожие темы

Комментарии