本文
C++でワイド文字列の静的配列(const wchar_t ...[];
)からstd::vector<std::wstring>
へ変換するにはstd::vector<std::wstring>
のコンストラクタを使用します。引数には静的配列の(変換したい範囲の)最初と最後要素のアドレスを渡します。このコンストラクタはcpprefjpではイテレータ範囲コンストラクタと呼ばれています。
生の配列のコード
C++標準ライブラリのstd::size
、std::begin
、std::end
、std::cbegin
、std::cend
には生の配列に対する特殊化が用意されています。次のどの方法でも書けます。
#include <string> #include <vector> int main() { const wchar_t* a[3]{L"abc", L"def", L"ghi"}; // constイテレーター std::vector<std::wstring> v1(std::cbegin(a), std::cend(a)); // ポインタ演算 std::vector<std::wstring> v2(a, a + std::size(a)); // constイテレーターとポインタ演算 std::vector<std::wstring> v3(std::cbegin(a), std::cbegin(a) + std::size(a)); // 非constイテレーター std::vector<std::wstring> v4(std::begin(a), std::end(a)); // 非constイテレーターとポインタ演算 std::vector<std::wstring> v5(std::begin(a), std::begin(a) + std::size(a)); return 0; }
STLコンテナのコード
std::array
はsize
、begin
、end
、cbegin
、cend
をメンバー関数として持つため、生の配列と同名の関数で同様に使用できます。std::~
を使えば生の配列と同様の記述も可能です。
#include <array> #include <string> #include <vector> int main() { std::array<const wchar_t*, 3> a{ L"abc", L"def", L"ghi" }; // constイテレーター std::vector<std::wstring> v1(a.cbegin(), a.cend()); // 非constイテレーター std::vector<std::wstring> v2(a.begin(), a.end()); // constイテレーターとポインタ演算 std::vector<std::wstring> v3(a.cbegin(), a.cbegin() + a.size()); // ポインタ演算 std::vector<std::wstring> v4(a.data(), a.data() + a.size()); // 非constイテレーターとポインタ演算 std::vector<std::wstring> v5(a.begin(), a.begin() + a.size()); return 0; }
解説
std::vector<std::wstring>
コンストラクタの内部では、引数として与えた最初の要素から最後の要素に間接演算子*
を適用した結果を引数としてstd::wstring
のコンストラクタが呼び出されます(MSVCでの動作)。std::wstring
はconst wchar_t*
型から文字列を作成するコンストラクタを持つため、std::vector<std::wstring>
は静的配列の要素に対応した文字列を持つコンテナとして初期化されます。
補足
- 既存の
std::vector<std::wstring>
へワイド文字列配列の要素を追加する場合はstd::back_insert_iterator
とstd::copy
またはstd::copy_n
を使用します。 - 変換しながら要素を追加する場合は上記のイテレーターと
std::transform
が使えたと思います。 - C++20からは
range
コンセプトを使用できます。
イテレータ範囲コンストラクタのMSVCでの動作
MSVC(Microsoft Visual Studio Community 2019 16.9.0 Preview 2.0)ではイテレータ範囲コンストラクタはイテレーターの種類(タグ)により動作が変わります。