はじめに
C++で、vector<string>
などに格納された複数の文字列を、カンマ区切り(,
)のような特定の文字列を間に挟んで、一つの大きな文字列に連結したい場合があります。従来はfor
ループで手動で連結する必要がありましたが、C++23のRangesライブラリには、この処理を非常にエレガントに行うための**std::views::join_with
**が導入されました。
これは、join
ビュー(C++20)をさらに発展させたもので、要素と要素の間に区切り文字を挿入する機能が追加されています。
【前提】C++23とは?
C++23は、2023年に正式化されたC++言語の比較的新しい規格です。std::views::join_with
はこのC++23で追加された機能のため、利用するにはC++23に対応したコンパイラが必要です。
join_with
を使ったサンプルコード
このコードは、vector<string>
に格納されたいくつかの単語を、ハイフンとスペース(-
)を区切り文字として連結し、一つの文字列を生成します。
完成コード
#include <iostream>
#include <vector>
#include <string>
#include <ranges>
namespace views = std::ranges::views;
using namespace std;
int main() {
vector<string> words = {"C++", "Ranges", "Library"};
// 1. join_withビューを作成
// 各要素の間に "- " という区切り文字を挿入するビュー
auto joined_view = words | views::join_with(" - ");
// 2. ビューから新しいstringを構築
// ranges::to<string>() を使うのがよりモダンな方法 (C++23)
string result_string;
for (char c : joined_view) {
result_string += c;
}
cout << "連結された文字列: " << result_string << endl;
return 0;
}
実行結果
連結された文字列: C++ - Ranges - Library
コードの解説
auto joined_view = words | views::join_with(" - ");
views::join_with(" - ")
: 引数として渡された区切り文字または区切り文字列(この場合は" - "
)を使って、元のコンテナの要素を連結するビューを作成します。- ビュー:
joined_view
は、連結後の文字列そのものではなく、元のwords
コンテナと区切り文字を組み合わせた「眺め」を表現する軽量なオブジェクトです。実際の文字の連結は、for
ループなどで要素が必要になった時点で行われます(遅延評価)。
ビューからstring
への変換
join_with
が返すのはあくまでビュー(文字の範囲)なので、最終的にstd::string
として扱いたい場合は、変換が必要です。
// パターンA: ループで一文字ずつ追加
string result_string;
for (char c : joined_view) {
result_string += c;
}
// パターンB: イテレータペアを使う
string result_string(joined_view.begin(), joined_view.end());
// パターンC: ranges::to を使う (C++23, 最も推奨)
string result_string = joined_view | std::ranges::to<string>();
C++23環境では、パターンCのranges::to
を使うのが最も簡潔で意図が明確な書き方です。
まとめ
今回は、C++23のstd::views::join_with
を使って、文字列のコンテナを指定した区切り文字で連結する方法を解説しました。
コンテナ | views::join_with(区切り文字)
の構文で、連結されたビューを作成する。- ビューの結果を
std::string
に変換して利用する。
join_with
は、for
ループとif
文(最後の要素の後には区切り文字を付けない、など)を使った手動での文字列連結の複雑さを完全に排除し、コードを劇的にシンプルにしてくれます。