最終更新日時: 2026年03月11日 13時40分57秒 (JST)
Akira Takahashi が更新

履歴 編集

class template
<string_view>

# std::basic_string_view(C++17)

    namespace std {
      template <class CharT, class Traits = char_traits<CharT>>
      class basic_string_view;

      using string_view = basic_string_view<char>;
      using u8string_view = basic_string_view<char8_t>; // C++20から
      using u16string_view = basic_string_view<char16_t>;
      using u32string_view = basic_string_view<char32_t>;
      using wstring_view = basic_string_view<wchar_t>;
    }

## 概要

`std::basic_string_view`は、文字列の所有権を保持せず、文字列のコピーを持つのではなく参照をして、参照先の文字列を加工して扱うクラスである。

文字配列型である文字列リテラルに対して、`std::basic_string`クラスが持つような便利なメンバ関数群を使用できる。文字列リテラルは静的記憶域に保存されるため、文字列リテラルをこのクラスのオブジェクトに参照させて、そのオブジェクトを持ち回ったとしても参照先の文字列リテラルの寿命が尽きるような問題は発生しない。

    string_view sv = "Hello World"; // この式の評価がおわったあとも、文字列リテラル "Hello World" の寿命は尽きない
    string_view hello = sv.substr(0, 5); // 先頭5文字を抽出する

このクラスの実装としては、文字配列の参照する先頭文字へのポインタと、文字数の2つをメンバ変数として持つ。これらの変数を変動させることによって、部分文字列の抽出や、限定された範囲内での検索といったことを実現する。

このクラスは、トリビアルコピー可能である（C++23）

## メンバ関数

### 構築・破棄

名前 | 説明 | 対応バージョン
--- | --- | ---
`(constructor)` | コンストラクタ | C++17
`~basic_string_view() = default;` | デストラクタ | C++17
`basic_string_view& operator=(const basic_string_view&) = default;` `basic_string_view& operator=(basic_string_view&&) = default;` | 代入演算子 | C++17

### イテレータ

名前 | 説明 | 対応バージョン
--- | --- | ---
`begin` | 先頭の要素を指すイテレータを取得する | C++17
`end` | 末尾の次を指すイテレータを取得する | C++17
`cbegin` | 先頭の要素を指す読み取り専用イテレータを取得する | C++17
`cend` | 末尾の次を指す読み取り専用イテレータを取得する | C++17
`rbegin` | 末尾を指す逆イテレータを取得する | C++17
`rend` | 先頭の前を指す逆イテレータを取得する | C++17
`crbegin` | 末尾を指す読み取り専用逆イテレータを取得する | C++17
`crend` | 先頭の前を指す読み取り専用逆イテレータを取得する | C++17

### 領域

名前 | 説明 | 対応バージョン
--- | --- | ---
`size` | 文字列の長さを取得する | C++17
`length` | 文字列の長さを取得する | C++17
`max_size` | 参照可能な最大の文字列長を取得する | C++17
`empty` | 文字列が空かどうかを判定する | C++17

### 要素アクセス

名前 | 説明 | 対応バージョン
--- | --- | ---
`operator[]` | 任意の位置の文字を取得する | C++17
`at` | 任意の位置の文字を取得する | C++17
`front` | 先頭文字を取得する | C++17
`back` | 末尾文字を取得する | C++17
`data` | 文字配列表現を取得する | C++17

### 文字列の変更

名前 | 説明 | 対応バージョン
--- | --- | ---
`remove_prefix` | 先頭のN文字を削除する | C++17
`remove_suffix` | 末尾のN文字を削除する | C++17
`swap` | 他の`basic_string_view`オブジェクトとデータを入れ替える | C++17

### 文字列の操作

名前 | 説明 | 対応バージョン
--- | --- | ---
`copy` | 他の文字列に、自身の文字列をコピーする | C++17
`substr` | 部分文字列を取得する | C++17
`subview` | 部分文字列を取得する | C++26
`compare` | 他の文字列との比較を行う | C++17
`starts_with` | 指定の文字列で始まるかを判定する | C++20
`ends_with` | 指定の文字列で終わるかを判定する | C++20
`contains` | 指定の文字・文字列が含まれているかを判定する | C++23

### 検索

名前 | 説明 | 対応バージョン
--- | --- | ---
`find` | 指定文字列を検索する | C++17
`rfind` | 最後に現れる指定文字列を検索する | C++17
`find_first_of` | 最初に現れる指定文字を検索する | C++17
`find_last_of` | 最後に現れる指定文字を検索する | C++17
`find_first_not_of` | 先頭から、指定文字が見つからない位置を検索する | C++17
`find_last_not_of` | 末尾から、指定文字が見つからない位置を検索する | C++17

### メンバ定数

名前 | 説明 | 対応バージョン
--- | --- | ---
`npos` | 無効な位置を表す。`find`や`substr`などで使われる。 `static constexpr size_type npos = -1;` | C++17

### メンバ型

名前 | 説明 | 対応バージョン
--- | --- | ---
`traits_type` | 文字特性型 `Traits` | C++17
`value_type` | 文字型 `CharT` | C++17
`pointer` | ポインタ型 `value_type*` | C++17
`const_pointer` | `const`ポインタ型 `const value_type*` | C++17
`reference` | 参照型 `value_type&` | C++17
`const_reference` | `const`参照型 `const value_type&` | C++17
`const_iterator` | 読み取り専用イテレータ。実装定義。 要素の型は`value_type`。 ランダムアクセスイテレータと連続イテレータの要件を満たす | C++17
`iterator` | イテレータ `const_iterator` | C++17
`const_reverse_iterator` | 読み取り専用逆イテレータ `reverse_iterator<const_iterator>` | C++17
`reverse_iterator` | 逆順イテレータ `const_reverse_iterator` | C++17
`size_type` | 要素数を表す符号なし整数型 `size_t` | C++17
`difference_type` | イテレータの差を表す符号付き整数型 `ptrdiff_t` | C++17

## 非メンバ関数

### 文字列連結

名前 | 説明 | 対応バージョン
--- | --- | ---
`operator+` | 文字列の連結 | C++26

### 比較演算

名前 | 説明 | 対応バージョン
--- | --- | ---
`operator==` | 等値比較 | C++17
`operator!=` | 非等値比較 | C++17
`operator<=>` | 三方比較 | C++20
`operator<` | 左辺が右辺より小さいかの判定を行う | C++17
`operator<=` | 左辺が右辺以下かの判定を行う | C++17
`operator>` | 左辺が右辺より大きいかの判定を行う | C++17
`operator>=` | 左辺が右辺以上かの判定を行う | C++17

### 入出力

名前 | 説明 | 対応バージョン
--- | --- | ---
`operator<<` | ストリームへの出力 | C++17

### 推論ガイド

名前 | 説明 | 対応バージョン
--- | --- | ---
`(deduction_guide)` | クラステンプレートの推論補助 | C++20

### リテラル

名前 | 説明 | 対応バージョン
--- | --- | ---
`sv` | `basic_string_view`のリテラル | C++17

## ハッシュサポート

名前 | 説明 | 対応バージョン
--- | --- | ---
`template <class T> struct hash;` | `hash`クラスの先行宣言 | C++17
`template <> struct hash<string_view>;` | `hash`クラスの`string_view`に対する特殊化 | C++17
`template <> struct hash<wstring_view>;` | `hash`クラスの`wstring_view`に対する特殊化 | C++17
`template <> struct hash<u8string_view>;` | `hash`クラスの`u8string_view`に対する特殊化 | C++20
`template <> struct hash<u16string_view>;` | `hash`クラスの`u16string_view`に対する特殊化 | C++17
`template <> struct hash<u32string_view>;` | `hash`クラスの`u32string_view`に対する特殊化 | C++17

上記の各`*string_view`に対する`hash`クラスの特殊化は、それぞれ対応する`*string`型に対する特殊化と同じハッシュ値を算出する。

## 例

### 基本的な使い方

    #include <iostream>
    #include <string_view>

    int main()
    {
      // 文字列リテラルから部分文字列を取得する。
      // その際、メモリアロケートは発生しない
      std::cout << std::string_view("Hello World").substr(0, 5) << std::endl;

      // 文字列リテラル内から特定の文字列を検索する。
      // この例でも、メモリアロケートや文字列オブジェクトのコピーなどは発生しない
      std::string_view sv = "Hello World";
      std::size_t pos = sv.find("rl");
      if (pos != std::string_view::npos) {
        std::cout << "found" << std::endl;
      }
    }

#### 出力

    Hello
    found

### stringとconst char*の共通インタフェースとして使用する

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

    // string, const char*、string_viewのどれでも受け取れる関数
    void f(std::string_view sv)
    {
      std::cout << sv.substr(0, 4) << std::endl;
    }

    int main()
    {
      // 文字列リテラル (char配列) を渡す
      f("Hello");

      // const char*を渡す
      const char* chars = "Hello";
      f(chars);

      // 左辺値のstringを渡す
      std::string s = "Hello";
      f(s);

      // stringの一時オブジェクトを渡す
      // 関数f()内ではこの一時オブジェクトが生存しているので、
      // string_view参照しても問題ない
      f(std::string("Hello"));
    }

#### 出力

    Hell
    Hell
    Hell
    Hell

### 文字列リテラルを範囲として使用する場合にヌル文字が含まれないようにする

    #include <iostream>
    #include <string_view>

    int main()
    {
      // 文字列リテラルを範囲として使用すると、ヌル文字が要素に含まれる
      std::cout << '[' << std::endl;
      for (char c : "ABC") {
        std::cout << c << std::endl;
      }
      std::cout << ']' << std::endl;

      // string_viewを使用すると、ヌル文字が要素に含まれない
      std::cout << '[' << std::endl;
      for (char c : std::string_view{"ABC"}) {
        std::cout << c << std::endl;
      }
      std::cout << ']' << std::endl;
    }

#### 出力

    [
    A
    B
    C

    ]
    [
    A
    B
    C
    ]

## バージョン

### 言語

- C++17

### 処理系

- Clang: 4.0 ✅
- GCC: 7.1 ✅
- ICC: ??
- Visual C++: ??

## 参照

- N3334 Proposing `array_ref<T>` and `string_ref`
- N3442 `string_ref`: a non-owning reference to a string
- N3512 `string_ref`: a non-owning reference to a string, revision 2
- N3609 `string_view`: a non-owning reference to a string, revision 3
- N3685 `string_view`: a non-owning reference to a string, revision 4
- N3762 `string_view`: a non-owning reference to a string, revision 5
- N3849 `string_view`: a non-owning reference to a string, revision 6
- N3921 `string_view`: a non-owning reference to a string, revision 7
- P0220R0 Adopt Library Fundamentals TS for C++17
- P0220R1 Adopt Library Fundamentals V1 TS Components for C++17 (R1)
- P0254R0 Integrating `std::string_view` and `std::string`
- P0254R1 Integrating `std::string_view` and `std::string`
- P0254R2 Integrating `std::string_view` and `std::string`
- P0403R0 Literal suffixes for `basic_string_view`
- LWG 2791 - `string_view` objects and strings should yield the same hash values
- String literals make bad ranges - Andrzej's C++ blog
- Require `span` & `basic_string_view` to be Trivially Copyable
  - C++23から、トリビアルコピー可能が保証される。