📢 Webサイト閉鎖と移転のお知らせ
このWebサイトは2026年9月に閉鎖いたします。
新しい記事は移転先で追加しております。(旧サイトでは記事を追加しておりません)

 
(同じ利用者による、間の1版が非表示)
46行目: 46行目:
<br><br>
<br><br>


== クロージャの例 1 ==
== クロージャの使用例 : 変数の保持 ==
以下の例では、func関数内でローカル変数xを定義して、それをラムダ式でキャプチャしている。<br>
以下の例では、func関数内でローカル変数xを定義して、それをラムダ式でキャプチャしている。<br>
ラムダ式は、変数xの値をコピーキャプチャ [=] して保持する。<br>
ラムダ式は、変数xの値をコピーキャプチャ [=] して保持する。<br>
136行目: 136行目:
  inc();
  inc();
  dec();
  dec();
</syntaxhighlight>
<br><br>
== クロージャの使用例 : 非同期処理のコールバック ==
以下の例では、非同期処理のコールバックをクロージャで実装、および、参照キャプチャを使用してカウンタを更新して、<br>
成功・失敗のカウントを保持している。<br>
<br>
<syntaxhighlight lang="c++">
#include <iostream>
#include <functional>
#include <stdexcept>
#include <string>
// 非同期処理を模擬した関数
void simulateAsyncOperation(const std::string& data, std::function<void(bool, const std::string&)> callback)
{
    try {
      // データの検証
      if (data.empty()) {
          throw std::invalid_argument("データが空です");
      }
      // 処理成功時のコールバック実行
      callback(true, "処理結果: " + data);
    }
    catch (const std::exception& e) {
      // エラー発生時のコールバック実行
      callback(false, std::string("エラー: ") + e.what());
    }
}
int main()
{
    int successCount = 0;  // 成功回数をカウント
    int failureCount = 0;  // 失敗回数をカウント
    // クロージャを作成
    // 成功・失敗のカウントを保持
    auto resultHandler = [&successCount, &failureCount](bool success, const std::string& result) {
      if (success) {
          successCount++;
          std::cout << "成功 (" << successCount << "回目): " << result << std::endl;
      }
      else {
          failureCount++;
          std::cout << "失敗 (" << failureCount << "回目): " << result << std::endl;
      }
    };
    // クロージャの実行
    simulateAsyncOperation("テストデータ1", resultHandler);
    simulateAsyncOperation("テストデータ2", resultHandler);
    simulateAsyncOperation("", resultHandler);            // エラーケース
 
    return 0;
}
</syntaxhighlight>
<br><br>
== クロージャの使用例 : カスタムソート ==
以下の例では、複雑なソート条件をクロージャで実装している。 <br>
複数の条件を組み合わせたソート、値キャプチャによる設定値の保持、構造体の入力値検証している。<br>
<br>
<syntaxhighlight lang="c++">
#include <iostream>
#include <vector>
#include <algorithm>
#include <stdexcept>
struct Product {
    std::string name;
    double      price;
    int        stock;
    Product(const std::string &n, double p, int s) : name(n), price(p), stock(s) {
      // 入力値の検証
      if (p < 0) throw std::invalid_argument("価格は0以上を入力");
      if (s < 0) throw std::invalid_argument("在庫数は0以上を入力");
    }
};
int main()
{
    try {
      // 商品データの作成
      std::vector<Product> products{
          Product("商品A", 1000, 5),
          Product("商品B", 2000, 3),
          Product("商品C", 1500, 0)
      };
      // ソート条件の優先順位を設定
      bool  prioritizeStock = true;  // 在庫優先フラグ
      double minPrice        = 1200;  // 価格の閾値
      // クロージャでソート条件を定義
      auto sortCondition = [prioritizeStock, minPrice](const Product& a, const Product& b) {
          if (prioritizeStock) {
            // 在庫がある商品を優先
            if ((a.stock > 0) != (b.stock > 0)) {
                return a.stock > 0;
            }
          }
          // 価格閾値との関係で比較
          bool a_above_threshold = a.price >= minPrice;
          bool b_above_threshold = b.price >= minPrice;
          if (a_above_threshold != b_above_threshold) {
            return !a_above_threshold;  // 閾値未満を優先
          }
          // 同条件の場合は価格の安い順
          return a.price < b.price;
      };
      // ソート実行
      std::sort(products.begin(), products.end(), sortCondition);
      // 結果表示
      std::cout << "ソート結果:" << std::endl;
      for (const auto &product : products) {
          std::cout << "商品名: " << product.name << ", 価格: " << product.price << ", 在庫: " << product.stock << std::endl;
      }
    }
    catch (const std::exception &e) {
      std::cerr << "エラーが発生: " << e.what() << std::endl;
      return -1;
    }
    return 0;
}
  </syntaxhighlight>
  </syntaxhighlight>
<br><br>
<br><br>