C++/スコープ
表示
< C++
導入
[編集]スコープとは何か?
[編集]プログラミングにおける「スコープ」とは、変数や関数が有効な範囲を定義する概念です。スコープは、変数や関数が宣言された場所によって決定され、それによってその変数や関数へのアクセス範囲が決まります。
スコープがコード内でどのように機能するかの概要
[編集]スコープは、コード内で変数や関数の可視性と生存期間を制御します。これにより、同じ名前の変数や関数が異なる場所で定義された場合でも、それぞれのスコープ内でのみアクセス可能であり、名前の衝突を避けることができます。
モダンC++におけるスコープ
[編集]基本的なスコープの種類
[編集]C++20以降では、以下の主要なスコープタイプが定義されています:
- ブロックスコープ - 中括弧
{}で囲まれた範囲 - 関数スコープ - 関数内全体
- 名前空間スコープ - 名前空間内全体
- クラススコープ - クラス定義内
- ファイルスコープ - ソースファイル内
- モジュールスコープ (C++20以降) - モジュール内
ブロックスコープ
[編集]ブロックスコープの定義
[編集]ブロックスコープは、中括弧{}で囲まれたコードブロック内で有効なスコープです。C++17以降では、初期化文を持つif文やswitch文でも独自のスコープを形成できます。
ブロックスコープ内での変数の有効性
[編集]ブロックスコープ内で宣言された変数は、そのブロック内でのみ有効です。C++17以降、構造化束縛宣言もブロックスコープに従います。
auto main() -> int { if (auto [x, y] = std::pair{1, 2}; x > 0) { // C++17構造化束縛 // xとyはこのブロック内でのみ有効 } return 0; }
for文スコープ
[編集]コード例(forループ内のスコープ)
[編集]C++20では、range-based forループでの初期化文もサポートされています:
auto main() -> int { std::vector<int> vec{1, 2, 3}; for (std::size_t i = 0; auto& elem : vec) { // C++20 std::cout << i++ << ": " << elem << '\n'; } return 0; }
名前空間
[編集]モダンな名前空間の使用
[編集]C++17以降では、入れ子名前空間を簡略化して記述できます:
namespace MyCompany::MyLibrary::MyFeature { // C++17 // 機能の実装 }
また、C++20では、モジュール内での名前空間の扱いも定義されています。
モジュールスコープ (C++20)
[編集]モジュールスコープの概要
[編集]C++20で導入されたモジュールは、新しいスコープレベルを提供します:
module; // グローバルモジュールフラグメント #include <string> export module my.module; // モジュール宣言 export namespace MyModule { auto getValue() -> std::string { return "Hello from module"; } }
コンセプトとスコープ (C++20)
[編集]コンセプトの可視性
[編集]C++20で導入されたコンセプトも、通常の名前空間規則に従います:
export module my.concepts; export template<typename T> concept Printable = requires(T t) { { std::cout << t } -> std::same_as<std::ostream&>; };
スコープとクラス
[編集]モダンC++でのクラススコープ
[編集]C++20以降、コンセプトやモジュールとの相互作用を含む、より豊かなクラススコープの機能が利用可能です:
export class MyClass { constexpr static int value = 42; public: auto getValue() const -> int requires std::is_constant_evaluated() { return value; } };
演習問題
[編集]- モジュールとクラススコープを組み合わせて使用し、モジュールをエクスポートする例を作成してください。
- C++20のコンセプトを使用して、特定の型に対する要件を定義し、それをテンプレート関数で使用する例を作成してください。
- 構造化束縛を使用して、複数の戻り値を持つ関数の結果を受け取り、それらの値をブロックスコープ内で使用する例を作成してください。