C++/配列とベクトル
表示
< C++
配列とベクトルの基本概念
[編集]配列とベクトルの定義と基本的な使い方
[編集]配列とベクトルは、複数の要素を格納するための主要なデータ構造です。配列は固定サイズの連続したメモリ領域に要素を格納し、要素の追加や削除が困難です。一方、ベクトルは動的にメモリを確保し、要素の追加や削除が容易です。
C++23では、これらのコンテナに対する操作がさらに強化され、より柔軟な使用が可能になっています。
モダンC++における配列とベクトルの選択
[編集]モダンC++では、以下の3つの主要な選択肢があります:
- 生の配列(Raw Array)
- 最も基本的だが、機能が限定的
std::array- 固定長配列の型安全な実装
std::vector- 動的サイズ配列の型安全な実装
std::arrayの使用
[編集]C++20以降のstd::array
[編集]std::arrayは固定長配列の型安全な実装を提供します:
#include <array> // C++20からは要素型と要素数の推論が改善 auto arr1 = std::array{1, 2, 3, 4, 5}; // std::array<int, 5> auto arr2 = std::array<double, 3>{1.0, 2.0, 3.0}; // C++23からは、より柔軟な集成体初期化が可能 std::array<int, 3> arr3{.value = {1, 2, 3}};
std::arrayの新機能
[編集]C++23では、std::arrayに以下の機能が追加されています:
constexpr操作の強化- 要素アクセスの最適化
- パターンマッチングのサポート
std::vectorの使用
[編集]C++20以降のstd::vector
[編集]std::vectorは動的配列の型安全な実装を提供し、C++20以降で多くの改善が加えられています:
#include <vector> // C++20からの型推論と初期化の改善 auto vec1 = std::vector{1, 2, 3, 4, 5}; // C++23からのより柔軟なメモリ管理 std::vector<int> vec2; vec2.reserve(100); // 最適化されたメモリ予約 vec2.resize(50); // 最適化されたリサイズ // C++23からの新しいイテレータ操作 auto pos = std::ranges::find(vec2, 3); if (pos != vec2.end()) { // 要素が見つかった場合の処理 }
vectorの新機能
[編集]C++23で追加された主な機能:
- コンストラクタの最適化
- メモリ管理の改善
constexpr対応の強化- パターンマッチングのサポート
スパンの活用
[編集]std::spanによる配列の参照
[編集]C++20で導入されたstd::spanは、配列やベクトルの参照を安全に扱うための機能を提供します:
#include <span> void processArray(std::span<int> data) { for (int& value : data) { // 処理 } } // 使用例 std::array<int, 5> arr{1, 2, 3, 4, 5}; std::vector<int> vec{1, 2, 3, 4, 5}; processArray(arr); processArray(vec);
ranges機能の活用
[編集]C++20のrangesライブラリ
[編集]C++20で導入されたrangesライブラリは、配列やベクトルの操作をより直感的にします:
#include <ranges> auto vec = std::vector{1, 2, 3, 4, 5}; // 値の変換 auto transformed = vec | std::views::transform([](int n) { return n * 2; }); // フィルタリング auto filtered = vec | std::views::filter([](int n) { return n % 2 == 0; }); // パイプライン処理 auto result = vec | std::views::filter([](int n) { return n % 2 == 0; }) | std::views::transform([](int n) { return n * 2; });
コンテナの操作
[編集]モダンな要素アクセス
[編集]C++23では、コンテナの要素アクセスが改善されています:
// イテレータを使用した安全なアクセス for (auto it = vec.begin(); it != vec.end(); ++it) { *it *= 2; // 要素の変更 } // 範囲forループによる簡潔なアクセス for (auto& elem : vec) { elem *= 2; } // std::rangesを使用した宣言的なアプローチ std::ranges::for_each(vec, [](auto& elem) { elem *= 2; });
パフォーマンスの最適化
[編集]C++23では、以下のようなパフォーマンス最適化が可能です:
- Small Buffer Optimization (SBO)の改善
- メモリアロケーションの最適化
- 移動セマンティクスの強化
実践的なテクニック
[編集]エラー処理
[編集]C++23では、より堅牢なエラー処理が可能になっています:
// 範囲チェック付きアクセス try { auto& elem = vec.at(5); } catch (const std::out_of_range& e) { // 範囲外アクセスの処理 } // C++23からのより効率的な例外処理 auto result = vec.try_emplace(5, 42); if (!result) { // エラー処理 }
メモリ管理
[編集]効率的なメモリ管理のためのベストプラクティス:
reserve()による事前メモリ確保shrink_to_fit()による未使用メモリの解放- カスタムアロケータの活用
新機能とベストプラクティス
[編集]C++23の新機能
[編集]- monadic操作のサポート
- パターンマッチング
- より強力な
constexprサポート - メモリ管理の最適化
推奨される使用パターン
[編集]- 固定長配列には
std::arrayを使用 - 動的サイズには
std::vectorを使用 - 参照には
std::spanを活用 - アルゴリズムには
rangesを使用