はじめに
C++で、関数に文字列を渡す際、引数を const std::string& とするのが一般的でした。しかし、この方法にはパフォーマンス上の問題があります。もし、関数にC言語スタイルの文字列リテラル(例: "Hello") を渡そうとすると、その場で一時的な std::string オブジェクトが生成され、メモリ確保とコピーが発生してしまうのです。
この問題を解決するのが、C++17で導入された std::string_view です。string_view は、既存の文字列データの「一部分」または「全部」を指し示すだけの、所有権を持たない軽量なオブジェクトです。
この記事では、string_view がどのようにして不要な文字列コピーを防ぎ、コードのパフォーマンスを向上させるのかを解説します。
【前提】C++17とは?
C++17は、2017年に正式化されたC++言語の規格です。std::string_view はこのC++17で導入されたため、利用するにはC++17に対応したコンパイラが必要です。
string_view を使ったサンプルコード
このコードは、文字列の一部を切り出して表示する関数を、従来の const string& を使った場合と、string_view を使った場合の2通りで定義し、その使われ方の違いを示します。
完成コード
#include <iostream>
#include <string>
#include <string_view> // string_view を使うために必要
using namespace std;
// 従来の const string& を使う関数
void printSubstring_String(const string& s) {
cout << s.substr(0, 5) << endl;
}
// C++17の string_view を使う関数
void printSubstring_StringView(string_view sv) {
cout << sv.substr(0, 5) << endl;
}
int main() {
string my_string = "Hello, Modern C++";
const char* c_style_string = "This is a C-style string";
cout << "--- const string& を使った場合 ---" << endl;
// string を渡す -> コピーは発生しない
printSubstring_String(my_string);
// C言語スタイル文字列を渡す -> 一時的なstringオブジェクトが生成され、コピーが発生
printSubstring_String(c_style_string);
cout << "\n--- string_view を使った場合 ---" << endl;
// string を渡す -> コピーは発生しない
printSubstring_StringView(my_string);
// C言語スタイル文字列を渡す -> コピーは発生しない
printSubstring_StringView(c_style_string);
// string_view を渡す -> もちろんコピーは発生しない
printSubstring_StringView(string_view{"This is a string_view literal"});
return 0;
}
コードの解説
void printSubstring_String(const string& s)
この従来の関数に、C言語スタイルの文字列 c_style_string を渡すと、const string& 型の引数に合わせるために、一時的な std::string オブジェクトがその場で生成されます。この時、文字列 "This is a C-style string" を格納するためのメモリ確保と、文字のコピーが発生します。
void printSubstring_StringView(string_view sv)
この新しい関数は、引数として string_view を受け取ります。string_view は、std::string からも、C言語スタイルの文字列リテラルからも、コピーなしで構築できます。
printSubstring_StringView(my_string):string_viewはmy_stringの内部バッファを直接指し示します。printSubstring_StringView(c_style_string):string_viewはc_style_stringのメモリアドレスを直接指し示します。
いずれの場合も、新たなメモリ確保や文字列のコピーは一切発生しません。string_view は、ポインタと長さ情報を持つだけの非常に軽量なオブジェクトです。
string_view の注意点
string_view は、あくまで既存の文字列への「眺め」であり、データの所有権を持ちません。そのため、string_view が指し示している元の文字列が、string_view よりも先に破棄されてしまうと、「ダングリング(ぶら下がり)」状態になり、アクセスすると未定義の動作を引き起こします。
まとめ
今回は、C++17の std::string_view を使って、不要な文字列コピーを回避し、パフォーマンスを向上させる方法を解説しました。
std::string_viewは、文字列の所有権を持たない、読み取り専用のビュー。- 関数の引数を
const std::string&からstd::string_viewに変更することで、様々な種類の文字列をコピーコストなしで受け取れるようになる。 - 指し示している元の文字列の寿命には、常に注意を払う必要がある。
結論として、関数の引数で、文字列の所有権が必要なく、単に読み取るだけでよい場合は、常に const std::string& よりも std::string_view を使うのが、現代C++のベストプラクティスです。
副業から独立まで「稼げる」Webスキルを習得する(PR)
ここまで読んでいただきありがとうございます。 最後に宣伝をさせてください。
「副業を始めたいが、何から手をつければいいかわからない」「独学でスキルはついたが、収益化できていない」という悩みを持つ方には、マンツーマン指導のWebスクール**「メイカラ」**が適しています。
このスクールは、単に技術を教えるだけでなく、**「副業として具体的にどう稼ぐか」**という実務直結のノウハウ提供に特化している点が特徴です。
講師陣は、実際に「副業Webライターから1年で独立して月収100万円」を達成したプロや、現役で利益を出し続けているブロガーなど、確かな実績を持つプレイヤーのみで構成されています。そのため、机上の空論ではない、現場で通用する戦術を学ぶことができます。
副業に特化した強み
- 最短ルートの提示: 未経験からでも実績を出せるよう、マンツーマンで指導。
- AI活用の習得: 副業の時間対効果を最大化するための、正しいAI活用スキルも網羅。
- 案件獲得のチャンス: 運営がWebマーケティング会社であるため、実力次第で社内案件の紹介など、仕事に直結する可能性があります。
受講者の多くは、「在宅でできる仕事を探している」「副業を頑張りたい」という20代・30代・40代が中心です。
受講前には、講師による無料説明が行われます。無理な勧誘はなく、自分に合った副業スタイルやプランを相談できるため、まずは話を聞いてみることから始めてみてはいかがでしょうか。
