C++BuilderでC++17 string viewを使用する
概要
C++言語の文字列クラスといえばstd::stringがありますが、動的にメモリを確保するため、クラスの構築や変更操作にコストがかかります。また部分文字列を取る場合には文字列のコピーが発生するため、余計なオーバーヘッドがかかります。もし高速化のために不要な処理を避けたい場合は、std::stringのメンバー関数の恩恵が受けられず、独自コードを書かなければならないケースも少なくありません。
C++17では、低いコストで文字列の構築や変更操作が可能なstd::string_view型が導入されました。
std::string_viewは、文字列の所有権を保持せず、文字列のコピーを持つのではなく参照をして、参照先の文字列を加工して扱います。
つまりstd::string_viewは、参照先の文字列の開始位置のポインタと長さを保持しており、文字列のコピーをすることなく文字列を参照できるため、std::stringのように動的なメモリ確保を必要とせず、余計なコピーも発生しないため、低いコストで文字列を扱うことができます。
C++Builderでstd::string_viewを使用するには?
- string_view は <string_view> ヘッダファイルに存在します。
std::string_viewのメリットは?
- std::string_viewは、不要な重複を避けたい場合に便利
- リテラルからstd::string_viewを作成する場合、動的なメモリ確保は不要
実際のコード例を見てみましょう。
#ifdef _WIN32
#include
#else
typedef char _TCHAR;
#define _tmain main
#endif
#include
#include
#include
#include
#include
// string_view
// Unified way to view a string (memory and length) - without owning it
// No allocation
std::size_t parse(std::string_view str) {
return std::count(str.begin(), str.end(), 'e');
}
int _tmain(int argc, _TCHAR *argv[]) {
const std::string str = "hello world";
const char* c = "Rio de Janeiro";
std::cout << "Occurrences of letter 'e': " << parse(std::string_view(str.data(), str.length())) << std::endl;
std::cout << "Occurrences of letter 'e': " << parse(std::string_view(c, strlen(c))) << std::endl;
system("pause");
return 0;
}
上記のコードでは、std::string_viewが不要なメモリ確保を制限することによって、メモリ節約を行なっています。std::string_viewは、素晴らしいパフォーマンスを発揮するための並外れたユーティリティですが、プログラマーはstd :: string_viewが参照している文字列よりも寿命が長続きしないことを保証する必要があります。
std::string_viewをもっと詳しく知りたい方は、公式のドキュメントを参考ください。また、このブログで紹介しましたサンプルコードは、こちらからダウンロードできます。