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
を使用