C++1z 文字配列をコピーせず参照してbasic_stringライクな操作をするstring_view

C++1zでは、所有権を持たない文字列クラスとして、basic_string_viewクラスが導入されます。その別名として、char文字配列を扱うstring_viewchar32_t文字配列を扱うu32string_viewなどが定義されます。

このクラスは、文字列リテラルような文字配列に対して、basic_stringクラスが提供するような便利なメンバ関数を使うためのものです。文字配列はbasic_stringクラスに代入できますが、その際に動的メモリ確保が行われます。しかし、basic_stringクラスの機能を使いたいだけで、basic_stringオブジェクトとして扱いたいわけではないという状況で、basic_string_viewクラスを使用します。

basic_string_viewクラスのために、<string_view>ヘッダが新設されます。

#include <iostream>
#include <string_view>

std::string_view extract_part(const std::string_view& str)
{
    // 文字列リテラルから部分文字列を抽出する
    return str.substr(2, 3);
}

int main()
{
    // 返された部分文字列の先頭文字を参照する
    if (extract_part("ABCDEFG").front() == 'C') {
        // …
    }
}

basic_string_viewは実装内部では文字配列へのポインタと長さくらいしか持たず、動的メモリ確保もしないので軽量です。

string_viewのリテラル

basic_string_viewクラス向けのsvというリテラル演算子も定義されます。

namespace std {
inline namespace literals {
inline namespace string_literals {

constexpr string_view    operator "" sv(const char* str, size_t len) noexcept;
constexpr u16string_view operator "" sv(const char16_t* str, size_t len) noexcept;
constexpr u32string_view operator "" sv(const char32_t* str, size_t len) noexcept;
constexpr wstring_view   operator "" sv(const wchar_t* str, size_t len) noexcept;

}
}
}
using namespace std::string_literals;
std::string_view sv = "ABCD"sv;

basic_stringとのインタフェース差異

std::basic_string_viewクラスは、std::basic_stringクラスとほぼ同じインタフェースを提供しますが、完全に同じではありません。ここでは、大きめな差異を示します:

  • basic_string_viewは、アロケータのインタフェースを持たない。クラスのテンプレートパラメータにAllocatorがなく、コンストラクタやメンバ関数のインタフェースもアロケータを受け取らない
  • basic_string_viewは、remove_prefix()remove_suffix()メンバ関数を持つ。ポインタを後ろにずらすか、長さを減らすかするだけの関数
  • basic_stringクラスのbasic_stringを受け取るインタフェースに、basic_string_viewクラスからの変換機能が追加される
  • basic_string_viewは、入力ストリーム演算子を持たない。出力ストリーム演算子は持つ
  • basic_string_viewは、assign()append()push_back()pop_back()insert()erase()replace()operator+=といった動的メモリ確保が必要になる操作や、破壊的な操作は持たない

Boost実装

  • basic_string_viewはBoostで実験的な実装が行われ、標準への最初の提案バージョンがBoost 1.59.0でbasic_string_refという名前で導入された
  • Boost 1.61.0でbasic_string_viewという名前に変更され、古い名前は非推奨となっている

参照

更新履歴

  • 2017/01/24 16:20 string_viewリテラルについて追記

お断り

この記事の内容は、C++1zが正式リリースされる際には変更される可能性があります。正式リリース後には、C++日本語リファレンスサイトcpprefjpの以下の階層の下に解説ページを用意する予定です。