📢 Webサイト閉鎖と移転のお知らせ
このWebサイトは2026年9月に閉鎖いたします。
新しい記事は移転先で追加しております。(旧サイトでは記事を追加しておりません)
| (同じ利用者による、間の1版が非表示) | |||
| 46行目: | 46行目: | ||
<br><br> | <br><br> | ||
== | == クロージャの使用例 : 変数の保持 == | ||
以下の例では、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> | ||