導入

編集

スコープとは何か?

編集

プログラミングにおける「スコープ」とは、変数や関数が有効な範囲を定義する概念です。スコープは、変数や関数が宣言された場所によって決定され、それによってその変数や関数へのアクセス範囲が決まります。

スコープがコード内でどのように機能するかの概要

編集

スコープは、コード内で変数や関数の可視性と生存期間を制御します。これにより、同じ名前の変数や関数が異なる場所で定義された場合でも、それぞれのスコープ内でのみアクセス可能であり、名前の衝突を避けることができます。

モダン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;
    }
};

演習問題

編集
  1. モジュールとクラススコープを組み合わせて使用し、モジュールをエクスポートする例を作成してください。
  2. C++20のコンセプトを使用して、特定の型に対する要件を定義し、それをテンプレート関数で使用する例を作成してください。
  3. 構造化束縛を使用して、複数の戻り値を持つ関数の結果を受け取り、それらの値をブロックスコープ内で使用する例を作成してください。